diff options
Diffstat (limited to 'contrib/llvm/tools/lldb/source/Commands/CommandObjectProcess.cpp')
-rw-r--r-- | contrib/llvm/tools/lldb/source/Commands/CommandObjectProcess.cpp | 303 |
1 files changed, 134 insertions, 169 deletions
diff --git a/contrib/llvm/tools/lldb/source/Commands/CommandObjectProcess.cpp b/contrib/llvm/tools/lldb/source/Commands/CommandObjectProcess.cpp index ec7b478..e587ead 100644 --- a/contrib/llvm/tools/lldb/source/Commands/CommandObjectProcess.cpp +++ b/contrib/llvm/tools/lldb/source/Commands/CommandObjectProcess.cpp @@ -7,8 +7,6 @@ // //===----------------------------------------------------------------------===// -#include "lldb/lldb-python.h" - #include "CommandObjectProcess.h" // C Includes @@ -22,6 +20,7 @@ #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" #include "lldb/Host/Host.h" +#include "lldb/Host/StringConvert.h" #include "lldb/Interpreter/Args.h" #include "lldb/Interpreter/Options.h" #include "lldb/Interpreter/CommandInterpreter.h" @@ -31,6 +30,7 @@ #include "lldb/Target/StopInfo.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" +#include "lldb/Target/UnixSignals.h" using namespace lldb; using namespace lldb_private; @@ -91,7 +91,7 @@ protected: } else { - Error destroy_error (process->Destroy()); + Error destroy_error (process->Destroy(false)); if (destroy_error.Success()) { result.SetStatus (eReturnStatusSuccessFinishResult); @@ -123,7 +123,7 @@ public: "process launch", "Launch the executable in the debugger.", NULL, - eFlagRequiresTarget, + eCommandRequiresTarget, "restart"), m_options (interpreter) { @@ -248,9 +248,7 @@ protected: if (launch_args.GetArgumentCount() == 0) { - Args target_setting_args; - if (target->GetRunArguments(target_setting_args)) - m_options.launch_info.GetArguments().AppendArguments (target_setting_args); + m_options.launch_info.GetArguments().AppendArguments (target->GetProcessLaunchInfo().GetArguments()); } else { @@ -264,13 +262,18 @@ protected: if (error.Success()) { - const char *archname = exe_module_sp->GetArchitecture().GetArchitectureName(); ProcessSP process_sp (target->GetProcessSP()); if (process_sp) { + // There is a race condition where this thread will return up the call stack to the main command + // handler and show an (lldb) prompt before HandlePrivateEvent (from PrivateStateThread) has + // a chance to call PushProcessIOHandler(). + process_sp->SyncIOHandler (0, 2000); + const char *data = stream.GetData(); if (data && strlen(data) > 0) result.AppendMessage(stream.GetData()); + const char *archname = exe_module_sp->GetArchitecture().GetArchitectureName(); result.AppendMessageWithFormat ("Process %" PRIu64 " launched: '%s' (%s)\n", process_sp->GetID(), exe_module_sp->GetFileSpec().GetPath().c_str(), archname); result.SetStatus (eReturnStatusSuccessFinishResult); result.SetDidChangeProcessState (true); @@ -353,7 +356,7 @@ public: case 'p': { - lldb::pid_t pid = Args::StringToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success); + lldb::pid_t pid = StringConvert::ToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success); if (!success || pid == LLDB_INVALID_PROCESS_ID) { error.SetErrorStringWithFormat("invalid process ID '%s'", option_arg); @@ -488,6 +491,8 @@ protected: DoExecute (Args& command, CommandReturnObject &result) { + PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform()); + Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); // N.B. The attach should be synchronous. It doesn't help much to get the prompt back between initiating the attach // and the target actually stopping. So even if the interpreter is set to be asynchronous, we wait for the stop @@ -530,118 +535,75 @@ protected: { result.AppendErrorWithFormat("Invalid arguments for '%s'.\nUsage: %s\n", m_cmd_name.c_str(), m_cmd_syntax.c_str()); result.SetStatus (eReturnStatusFailed); + return false; } - else + + m_interpreter.UpdateExecutionContext(nullptr); + StreamString stream; + const auto error = target->Attach(m_options.attach_info, &stream); + if (error.Success()) { - if (state != eStateConnected) + ProcessSP process_sp (target->GetProcessSP()); + if (process_sp) { - const char *plugin_name = m_options.attach_info.GetProcessPluginName(); - process = target->CreateProcess (m_interpreter.GetDebugger().GetListener(), plugin_name, NULL).get(); + if (stream.GetData()) + result.AppendMessage(stream.GetData()); + result.SetStatus (eReturnStatusSuccessFinishNoResult); + result.SetDidChangeProcessState (true); } - - if (process) + else { - Error error; - // If no process info was specified, then use the target executable - // name as the process to attach to by default - if (!m_options.attach_info.ProcessInfoSpecified ()) - { - if (old_exec_module_sp) - m_options.attach_info.GetExecutableFile().GetFilename() = old_exec_module_sp->GetPlatformFileSpec().GetFilename(); + result.AppendError("no error returned from Target::Attach, and target has no process"); + result.SetStatus (eReturnStatusFailed); + } + } + else + { + result.AppendErrorWithFormat ("attach failed: %s\n", error.AsCString()); + result.SetStatus (eReturnStatusFailed); + } - if (!m_options.attach_info.ProcessInfoSpecified ()) - { - error.SetErrorString ("no process specified, create a target with a file, or specify the --pid or --name command option"); - } - } + if (!result.Succeeded()) + return false; - if (error.Success()) - { - // Update the execution context so the current target and process are now selected - // in case we interrupt - m_interpreter.UpdateExecutionContext(NULL); - ListenerSP listener_sp (new Listener("lldb.CommandObjectProcessAttach.DoExecute.attach.hijack")); - m_options.attach_info.SetHijackListener(listener_sp); - process->HijackProcessEvents(listener_sp.get()); - error = process->Attach (m_options.attach_info); - - if (error.Success()) - { - result.SetStatus (eReturnStatusSuccessContinuingNoResult); - StreamString stream; - StateType state = process->WaitForProcessToStop (NULL, NULL, false, listener_sp.get(), &stream); + // Okay, we're done. Last step is to warn if the executable module has changed: + char new_path[PATH_MAX]; + ModuleSP new_exec_module_sp (target->GetExecutableModule()); + if (!old_exec_module_sp) + { + // We might not have a module if we attached to a raw pid... + if (new_exec_module_sp) + { + new_exec_module_sp->GetFileSpec().GetPath(new_path, PATH_MAX); + result.AppendMessageWithFormat("Executable module set to \"%s\".\n", new_path); + } + } + else if (old_exec_module_sp->GetFileSpec() != new_exec_module_sp->GetFileSpec()) + { + char old_path[PATH_MAX]; - process->RestoreProcessEvents(); + old_exec_module_sp->GetFileSpec().GetPath (old_path, PATH_MAX); + new_exec_module_sp->GetFileSpec().GetPath (new_path, PATH_MAX); - result.SetDidChangeProcessState (true); - - if (stream.GetData()) - result.AppendMessage(stream.GetData()); + result.AppendWarningWithFormat("Executable module changed from \"%s\" to \"%s\".\n", + old_path, new_path); + } - if (state == eStateStopped) - { - result.SetStatus (eReturnStatusSuccessFinishNoResult); - } - else - { - const char *exit_desc = process->GetExitDescription(); - if (exit_desc) - result.AppendErrorWithFormat ("attach failed: %s", exit_desc); - else - result.AppendError ("attach failed: process did not stop (no such process or permission problem?)"); - process->Destroy(); - result.SetStatus (eReturnStatusFailed); - } - } - else - { - result.AppendErrorWithFormat ("attach failed: %s\n", error.AsCString()); - result.SetStatus (eReturnStatusFailed); - } - } - } + if (!old_arch_spec.IsValid()) + { + result.AppendMessageWithFormat ("Architecture set to: %s.\n", target->GetArchitecture().GetTriple().getTriple().c_str()); } - - if (result.Succeeded()) + else if (!old_arch_spec.IsExactMatch(target->GetArchitecture())) { - // Okay, we're done. Last step is to warn if the executable module has changed: - char new_path[PATH_MAX]; - ModuleSP new_exec_module_sp (target->GetExecutableModule()); - if (!old_exec_module_sp) - { - // We might not have a module if we attached to a raw pid... - if (new_exec_module_sp) - { - new_exec_module_sp->GetFileSpec().GetPath(new_path, PATH_MAX); - result.AppendMessageWithFormat("Executable module set to \"%s\".\n", new_path); - } - } - else if (old_exec_module_sp->GetFileSpec() != new_exec_module_sp->GetFileSpec()) - { - char old_path[PATH_MAX]; - - old_exec_module_sp->GetFileSpec().GetPath (old_path, PATH_MAX); - new_exec_module_sp->GetFileSpec().GetPath (new_path, PATH_MAX); - - result.AppendWarningWithFormat("Executable module changed from \"%s\" to \"%s\".\n", - old_path, new_path); - } - - if (!old_arch_spec.IsValid()) - { - result.AppendMessageWithFormat ("Architecture set to: %s.\n", target->GetArchitecture().GetTriple().getTriple().c_str()); - } - else if (!old_arch_spec.IsExactMatch(target->GetArchitecture())) - { - result.AppendWarningWithFormat("Architecture changed from %s to %s.\n", - old_arch_spec.GetTriple().getTriple().c_str(), - target->GetArchitecture().GetTriple().getTriple().c_str()); - } - - // This supports the use-case scenario of immediately continuing the process once attached. - if (m_options.attach_info.GetContinueOnceAttached()) - m_interpreter.HandleCommand("process continue", eLazyBoolNo, result); + result.AppendWarningWithFormat("Architecture changed from %s to %s.\n", + old_arch_spec.GetTriple().getTriple().c_str(), + target->GetArchitecture().GetTriple().getTriple().c_str()); } + + // This supports the use-case scenario of immediately continuing the process once attached. + if (m_options.attach_info.GetContinueOnceAttached()) + m_interpreter.HandleCommand("process continue", eLazyBoolNo, result); + return result.Succeeded(); } @@ -675,10 +637,10 @@ public: "process continue", "Continue execution of all threads in the current process.", "process continue", - eFlagRequiresProcess | - eFlagTryTargetAPILock | - eFlagProcessMustBeLaunched | - eFlagProcessMustBePaused ), + eCommandRequiresProcess | + eCommandTryTargetAPILock | + eCommandProcessMustBeLaunched | + eCommandProcessMustBePaused ), m_options(interpreter) { } @@ -714,7 +676,7 @@ protected: switch (short_option) { case 'i': - m_ignore = Args::StringToUInt32 (option_arg, 0, 0, &success); + m_ignore = StringConvert::ToUInt32 (option_arg, 0, 0, &success); if (!success) error.SetErrorStringWithFormat ("invalid value for ignore option: \"%s\", should be a number.", option_arg); break; @@ -798,6 +760,8 @@ protected: } } + const uint32_t iohandler_id = process->GetIOHandlerID(); + StreamString stream; Error error; if (synchronous_execution) @@ -808,9 +772,9 @@ protected: if (error.Success()) { // There is a race condition where this thread will return up the call stack to the main command - // handler and show an (lldb) prompt before HandlePrivateEvent (from PrivateStateThread) has - // a chance to call PushProcessIOHandler(). - process->SyncIOHandler(2000); + // handler and show an (lldb) prompt before HandlePrivateEvent (from PrivateStateThread) has + // a chance to call PushProcessIOHandler(). + process->SyncIOHandler(iohandler_id, 2000); result.AppendMessageWithFormat ("Process %" PRIu64 " resuming\n", process->GetID()); if (synchronous_execution) @@ -936,9 +900,9 @@ public: "process detach", "Detach from the current process being debugged.", "process detach", - eFlagRequiresProcess | - eFlagTryTargetAPILock | - eFlagProcessMustBeLaunched), + eCommandRequiresProcess | + eCommandTryTargetAPILock | + eCommandProcessMustBeLaunched), m_options(interpreter) { } @@ -1217,10 +1181,10 @@ public: "process load", "Load a shared library into the current process.", "process load <filename> [<filename> ...]", - eFlagRequiresProcess | - eFlagTryTargetAPILock | - eFlagProcessMustBeLaunched | - eFlagProcessMustBePaused ) + eCommandRequiresProcess | + eCommandTryTargetAPILock | + eCommandProcessMustBeLaunched | + eCommandProcessMustBePaused ) { } @@ -1274,10 +1238,10 @@ public: "process unload", "Unload a shared library from the current process using the index returned by a previous call to \"process load\".", "process unload <index>", - eFlagRequiresProcess | - eFlagTryTargetAPILock | - eFlagProcessMustBeLaunched | - eFlagProcessMustBePaused ) + eCommandRequiresProcess | + eCommandTryTargetAPILock | + eCommandProcessMustBeLaunched | + eCommandProcessMustBePaused ) { } @@ -1297,7 +1261,7 @@ protected: for (uint32_t i=0; i<argc; ++i) { const char *image_token_cstr = command.GetArgumentAtIndex(i); - uint32_t image_token = Args::StringToUInt32(image_token_cstr, LLDB_INVALID_IMAGE_TOKEN, 0); + uint32_t image_token = StringConvert::ToUInt32(image_token_cstr, LLDB_INVALID_IMAGE_TOKEN, 0); if (image_token == LLDB_INVALID_IMAGE_TOKEN) { result.AppendErrorWithFormat ("invalid image index argument '%s'", image_token_cstr); @@ -1338,7 +1302,7 @@ public: "process signal", "Send a UNIX signal to the current process being debugged.", NULL, - eFlagRequiresProcess | eFlagTryTargetAPILock) + eCommandRequiresProcess | eCommandTryTargetAPILock) { CommandArgumentEntry arg; CommandArgumentData signal_arg; @@ -1371,9 +1335,9 @@ protected: const char *signal_name = command.GetArgumentAtIndex(0); if (::isxdigit (signal_name[0])) - signo = Args::StringToSInt32(signal_name, LLDB_INVALID_SIGNAL_NUMBER, 0); + signo = StringConvert::ToSInt32(signal_name, LLDB_INVALID_SIGNAL_NUMBER, 0); else - signo = process->GetUnixSignals().GetSignalNumberFromName (signal_name); + signo = process->GetUnixSignals()->GetSignalNumberFromName(signal_name); if (signo == LLDB_INVALID_SIGNAL_NUMBER) { @@ -1420,9 +1384,9 @@ public: "process interrupt", "Interrupt the current process being debugged.", "process interrupt", - eFlagRequiresProcess | - eFlagTryTargetAPILock | - eFlagProcessMustBeLaunched) + eCommandRequiresProcess | + eCommandTryTargetAPILock | + eCommandProcessMustBeLaunched) { } @@ -1482,9 +1446,9 @@ public: "process kill", "Terminate the current process being debugged.", "process kill", - eFlagRequiresProcess | - eFlagTryTargetAPILock | - eFlagProcessMustBeLaunched) + eCommandRequiresProcess | + eCommandTryTargetAPILock | + eCommandProcessMustBeLaunched) { } @@ -1507,7 +1471,7 @@ protected: if (command.GetArgumentCount() == 0) { - Error error (process->Destroy()); + Error error (process->Destroy(true)); if (error.Success()) { result.SetStatus (eReturnStatusSuccessFinishResult); @@ -1543,9 +1507,9 @@ public: "process save-core", "Save the current process as a core file using an appropriate file type.", "process save-core FILE", - eFlagRequiresProcess | - eFlagTryTargetAPILock | - eFlagProcessMustBeLaunched) + eCommandRequiresProcess | + eCommandTryTargetAPILock | + eCommandProcessMustBeLaunched) { } @@ -1607,7 +1571,7 @@ public: "process status", "Show the current status and location of executing process.", "process status", - eFlagRequiresProcess | eFlagTryTargetAPILock) + eCommandRequiresProcess | eCommandTryTargetAPILock) { } @@ -1621,7 +1585,7 @@ public: { Stream &strm = result.GetOutputStream(); result.SetStatus (eReturnStatusSuccessFinishNoResult); - // No need to check "process" for validity as eFlagRequiresProcess ensures it is valid + // No need to check "process" for validity as eCommandRequiresProcess ensures it is valid Process *process = m_exe_ctx.GetProcessPtr(); const bool only_threads_with_stop_reason = true; const uint32_t start_frame = 0; @@ -1717,7 +1681,8 @@ public: NULL), m_options (interpreter) { - SetHelpLong ("If no signals are specified, update them all. If no update option is specified, list the current values.\n"); + SetHelpLong ("\nIf no signals are specified, update them all. If no update " + "option is specified, list the current values."); CommandArgumentEntry arg; CommandArgumentData signal_arg; @@ -1754,7 +1719,7 @@ public: else { // If the value isn't 'true' or 'false', it had better be 0 or 1. - real_value = Args::StringToUInt32 (option.c_str(), 3); + real_value = StringConvert::ToUInt32 (option.c_str(), 3); if (real_value != 0 && real_value != 1) okay = false; } @@ -1765,19 +1730,19 @@ public: void PrintSignalHeader (Stream &str) { - str.Printf ("NAME PASS STOP NOTIFY\n"); - str.Printf ("========== ===== ===== ======\n"); + str.Printf ("NAME PASS STOP NOTIFY\n"); + str.Printf ("=========== ===== ===== ======\n"); } void - PrintSignal (Stream &str, int32_t signo, const char *sig_name, UnixSignals &signals) + PrintSignal(Stream &str, int32_t signo, const char *sig_name, const UnixSignalsSP &signals_sp) { bool stop; bool suppress; bool notify; - str.Printf ("%-10s ", sig_name); - if (signals.GetSignalInfo (signo, suppress, stop, notify)) + str.Printf ("%-11s ", sig_name); + if (signals_sp->GetSignalInfo(signo, suppress, stop, notify)) { bool pass = !suppress; str.Printf ("%s %s %s", @@ -1789,7 +1754,7 @@ public: } void - PrintSignalInformation (Stream &str, Args &signal_args, int num_valid_signals, UnixSignals &signals) + PrintSignalInformation(Stream &str, Args &signal_args, int num_valid_signals, const UnixSignalsSP &signals_sp) { PrintSignalHeader (str); @@ -1798,18 +1763,18 @@ public: size_t num_args = signal_args.GetArgumentCount(); for (size_t i = 0; i < num_args; ++i) { - int32_t signo = signals.GetSignalNumberFromName (signal_args.GetArgumentAtIndex (i)); + int32_t signo = signals_sp->GetSignalNumberFromName(signal_args.GetArgumentAtIndex(i)); if (signo != LLDB_INVALID_SIGNAL_NUMBER) - PrintSignal (str, signo, signal_args.GetArgumentAtIndex (i), signals); + PrintSignal (str, signo, signal_args.GetArgumentAtIndex (i), signals_sp); } } else // Print info for ALL signals { - int32_t signo = signals.GetFirstSignalNumber(); + int32_t signo = signals_sp->GetFirstSignalNumber(); while (signo != LLDB_INVALID_SIGNAL_NUMBER) { - PrintSignal (str, signo, signals.GetSignalAsCString (signo), signals); - signo = signals.GetNextSignalNumber (signo); + PrintSignal(str, signo, signals_sp->GetSignalAsCString(signo), signals_sp); + signo = signals_sp->GetNextSignalNumber(signo); } } } @@ -1866,27 +1831,27 @@ protected: } size_t num_args = signal_args.GetArgumentCount(); - UnixSignals &signals = process_sp->GetUnixSignals(); + UnixSignalsSP signals_sp = process_sp->GetUnixSignals(); int num_signals_set = 0; if (num_args > 0) { for (size_t i = 0; i < num_args; ++i) { - int32_t signo = signals.GetSignalNumberFromName (signal_args.GetArgumentAtIndex (i)); + int32_t signo = signals_sp->GetSignalNumberFromName(signal_args.GetArgumentAtIndex(i)); if (signo != LLDB_INVALID_SIGNAL_NUMBER) { // Casting the actions as bools here should be okay, because VerifyCommandOptionValue guarantees // the value is either 0 or 1. if (stop_action != -1) - signals.SetShouldStop (signo, (bool) stop_action); + signals_sp->SetShouldStop(signo, stop_action); if (pass_action != -1) { - bool suppress = ! ((bool) pass_action); - signals.SetShouldSuppress (signo, suppress); + bool suppress = !pass_action; + signals_sp->SetShouldSuppress(signo, suppress); } if (notify_action != -1) - signals.SetShouldNotify (signo, (bool) notify_action); + signals_sp->SetShouldNotify(signo, notify_action); ++num_signals_set; } else @@ -1902,25 +1867,25 @@ protected: { if (m_interpreter.Confirm ("Do you really want to update all the signals?", false)) { - int32_t signo = signals.GetFirstSignalNumber(); + int32_t signo = signals_sp->GetFirstSignalNumber(); while (signo != LLDB_INVALID_SIGNAL_NUMBER) { if (notify_action != -1) - signals.SetShouldNotify (signo, (bool) notify_action); + signals_sp->SetShouldNotify(signo, notify_action); if (stop_action != -1) - signals.SetShouldStop (signo, (bool) stop_action); + signals_sp->SetShouldStop(signo, stop_action); if (pass_action != -1) { - bool suppress = ! ((bool) pass_action); - signals.SetShouldSuppress (signo, suppress); + bool suppress = !pass_action; + signals_sp->SetShouldSuppress(signo, suppress); } - signo = signals.GetNextSignalNumber (signo); + signo = signals_sp->GetNextSignalNumber(signo); } } } } - PrintSignalInformation (result.GetOutputStream(), signal_args, num_signals_set, signals); + PrintSignalInformation (result.GetOutputStream(), signal_args, num_signals_set, signals_sp); if (num_signals_set > 0) result.SetStatus (eReturnStatusSuccessFinishNoResult); |