summaryrefslogtreecommitdiffstats
path: root/source/Commands/CommandObjectProcess.cpp
diff options
context:
space:
mode:
authoremaste <emaste@FreeBSD.org>2015-02-09 01:44:09 +0000
committeremaste <emaste@FreeBSD.org>2015-02-09 01:44:09 +0000
commitd61b076ede88b56f3372a55e7d1eac6a9d717120 (patch)
treea8f4b3abea3e6937e60728991c736e6e3d322fc1 /source/Commands/CommandObjectProcess.cpp
parent0c2019f4ca6b2dc6d710f6bb16a0e3ed10271531 (diff)
downloadFreeBSD-src-d61b076ede88b56f3372a55e7d1eac6a9d717120.zip
FreeBSD-src-d61b076ede88b56f3372a55e7d1eac6a9d717120.tar.gz
Import LLDB as of upstream SVN 228549 (git 39760838)
Diffstat (limited to 'source/Commands/CommandObjectProcess.cpp')
-rw-r--r--source/Commands/CommandObjectProcess.cpp201
1 files changed, 106 insertions, 95 deletions
diff --git a/source/Commands/CommandObjectProcess.cpp b/source/Commands/CommandObjectProcess.cpp
index ec7b478..d47311e 100644
--- a/source/Commands/CommandObjectProcess.cpp
+++ b/source/Commands/CommandObjectProcess.cpp
@@ -22,6 +22,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"
@@ -353,7 +354,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 +489,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
@@ -526,122 +529,130 @@ protected:
ModuleSP old_exec_module_sp = target->GetExecutableModule();
ArchSpec old_arch_spec = target->GetArchitecture();
+ ProcessSP process_sp;
+ Error error;
if (command.GetArgumentCount())
{
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);
+ ListenerSP listener_sp (new Listener("lldb.CommandObjectProcessAttach.DoExecute.attach.hijack"));
+ m_options.attach_info.SetHijackListener(listener_sp);
+
+ // 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 (state != eStateConnected)
+ if (old_exec_module_sp)
+ m_options.attach_info.GetExecutableFile().GetFilename() = old_exec_module_sp->GetPlatformFileSpec().GetFilename();
+
+ if (!m_options.attach_info.ProcessInfoSpecified ())
{
- const char *plugin_name = m_options.attach_info.GetProcessPluginName();
- process = target->CreateProcess (m_interpreter.GetDebugger().GetListener(), plugin_name, NULL).get();
+ error.SetErrorString ("no process specified, create a target with a file, or specify the --pid or --name command option");
}
+ }
- if (process)
+ if (error.Success())
+ {
+ if (state != eStateConnected && platform_sp != nullptr && platform_sp->CanDebugProcess())
+ {
+ target->SetPlatform(platform_sp);
+ process = platform_sp->Attach(m_options.attach_info, m_interpreter.GetDebugger(), target, error).get();
+ }
+ 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 (state != eStateConnected)
{
- if (old_exec_module_sp)
- m_options.attach_info.GetExecutableFile().GetFilename() = old_exec_module_sp->GetPlatformFileSpec().GetFilename();
-
- 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");
- }
+ const char *plugin_name = m_options.attach_info.GetProcessPluginName();
+ process = target->CreateProcess (m_interpreter.GetDebugger().GetListener(), plugin_name, nullptr).get();
+ if (process == nullptr)
+ error.SetErrorStringWithFormat("failed to create process using plugin %s", plugin_name);
}
-
- if (error.Success())
+ if (process)
{
- // 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);
-
- process->RestoreProcessEvents();
-
- result.SetDidChangeProcessState (true);
-
- if (stream.GetData())
- result.AppendMessage(stream.GetData());
-
- 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);
- }
+ error = process->Attach(m_options.attach_info);
}
}
}
-
- if (result.Succeeded())
+
+ if (error.Success() && process != nullptr)
{
- // 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)
+ result.SetStatus (eReturnStatusSuccessContinuingNoResult);
+ StreamString stream;
+ StateType state = process->WaitForProcessToStop (nullptr, nullptr, false, listener_sp.get(), &stream);
+
+ process->RestoreProcessEvents();
+ result.SetDidChangeProcessState (true);
+
+ if (stream.GetData())
+ result.AppendMessage(stream.GetData());
+
+ if (state == eStateStopped)
{
- // 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);
- }
+ result.SetStatus (eReturnStatusSuccessFinishNoResult);
}
- 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())
+ else
{
- result.AppendMessageWithFormat ("Architecture set to: %s.\n", target->GetArchitecture().GetTriple().getTriple().c_str());
+ 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 if (!old_arch_spec.IsExactMatch(target->GetArchitecture()))
+ }
+ else
+ {
+ result.AppendErrorWithFormat ("attach failed: %s\n", error.AsCString());
+ result.SetStatus (eReturnStatusFailed);
+ }
+
+ if (!result.Succeeded())
+ return false;
+
+ // 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)
{
- result.AppendWarningWithFormat("Architecture changed from %s to %s.\n",
- old_arch_spec.GetTriple().getTriple().c_str(),
- target->GetArchitecture().GetTriple().getTriple().c_str());
+ 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];
- // 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);
+ 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);
+
return result.Succeeded();
}
@@ -714,7 +725,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;
@@ -1297,7 +1308,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);
@@ -1371,7 +1382,7 @@ 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);
@@ -1754,7 +1765,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;
}
OpenPOWER on IntegriCloud