summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/include/lldb/Interpreter/Args.h3
-rw-r--r--lldb/include/lldb/Interpreter/CommandReturnObject.h4
-rw-r--r--lldb/include/lldb/Target/Platform.h2
-rw-r--r--lldb/include/lldb/Target/Process.h178
-rw-r--r--lldb/include/lldb/lldb-forward.h5
-rw-r--r--lldb/source/API/SBProcess.cpp4
-rw-r--r--lldb/source/API/SBTarget.cpp9
-rw-r--r--lldb/source/Commands/CommandObjectPlatform.cpp10
-rw-r--r--lldb/source/Commands/CommandObjectProcess.cpp238
-rw-r--r--lldb/source/Host/macosx/Host.mm89
-rw-r--r--lldb/source/Interpreter/Args.cpp20
-rw-r--r--lldb/source/Interpreter/CommandReturnObject.cpp10
-rw-r--r--lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp19
-rw-r--r--lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h2
-rw-r--r--lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp4
-rw-r--r--lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h2
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp2
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp2
-rw-r--r--lldb/source/Target/Platform.cpp12
-rw-r--r--lldb/source/Target/Process.cpp312
20 files changed, 558 insertions, 369 deletions
diff --git a/lldb/include/lldb/Interpreter/Args.h b/lldb/include/lldb/Interpreter/Args.h
index 580ebafba8f..a5b66ac387c 100644
--- a/lldb/include/lldb/Interpreter/Args.h
+++ b/lldb/include/lldb/Interpreter/Args.h
@@ -401,6 +401,9 @@ public:
static const char *
StringToVersion (const char *s, uint32_t &major, uint32_t &minor, uint32_t &update);
+ static const char *
+ GetShellSafeArgument (const char *unsafe_arg, std::string &safe_arg);
+
// This one isn't really relevant to Arguments per se, but we're using the Args as a
// general strings container, so...
void
diff --git a/lldb/include/lldb/Interpreter/CommandReturnObject.h b/lldb/include/lldb/Interpreter/CommandReturnObject.h
index 8b44cb7ea18..ce062d38845 100644
--- a/lldb/include/lldb/Interpreter/CommandReturnObject.h
+++ b/lldb/include/lldb/Interpreter/CommandReturnObject.h
@@ -141,6 +141,10 @@ public:
void
AppendErrorWithFormat (const char *format, ...) __attribute__ ((format (printf, 2, 3)));
+ void
+ SetError (const Error &error,
+ const char *fallback_error_cstr);
+
lldb::ReturnStatus
GetStatus();
diff --git a/lldb/include/lldb/Target/Platform.h b/lldb/include/lldb/Target/Platform.h
index 9d2e6ca2acb..76659b69914 100644
--- a/lldb/include/lldb/Target/Platform.h
+++ b/lldb/include/lldb/Target/Platform.h
@@ -305,7 +305,7 @@ namespace lldb_private {
/// appriopriate error fill into the \a error object.
//------------------------------------------------------------------
virtual lldb::ProcessSP
- Attach (lldb::pid_t pid,
+ Attach (ProcessAttachInfo &attach_info,
Debugger &debugger,
Target *target, // Can be NULL, if NULL create a new target, else use existing one
Listener &listener,
diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h
index e002932750a..95a41f45bc0 100644
--- a/lldb/include/lldb/Target/Process.h
+++ b/lldb/include/lldb/Target/Process.h
@@ -148,12 +148,6 @@ public:
return m_executable.GetFilename().GetLength();
}
- void
- SetName (const char *name)
- {
- m_executable.GetFilename().SetCString (name);
- }
-
FileSpec &
GetExecutableFile ()
{
@@ -591,7 +585,7 @@ public:
}
void
- FinalizeFileActions (Target *target, Process *process);
+ FinalizeFileActions (Target *target);
size_t
GetNumFileActions () const
@@ -671,21 +665,158 @@ public:
m_plugin_name.clear();
}
+ const char *
+ GetShell () const
+ {
+ if (m_shell.empty())
+ return NULL;
+ return m_shell.c_str();
+ }
+
+ void
+ SetShell (const char * path)
+ {
+ if (path && path[0])
+ {
+ m_shell.assign (path);
+ m_flags.Set (lldb::eLaunchFlagLaunchInShell);
+ }
+ else
+ {
+ m_shell.clear();
+ m_flags.Clear (lldb::eLaunchFlagLaunchInShell);
+ }
+ }
+
+ uint32_t
+ GetResumeCount () const
+ {
+ return m_resume_count;
+ }
+
+ void
+ SetResumeCount (uint32_t c)
+ {
+ m_resume_count = c;
+ }
+
void
Clear ()
{
ProcessInfo::Clear();
m_working_dir.clear();
m_plugin_name.clear();
+ m_shell.clear();
m_flags.Clear();
m_file_actions.clear();
+ m_resume_count = 0;
}
+ bool
+ ConvertArgumentsForLaunchingInShell (Error &error, bool localhost);
+
protected:
std::string m_working_dir;
std::string m_plugin_name;
+ std::string m_shell;
Flags m_flags; // Bitwise OR of bits from lldb::LaunchFlags
std::vector<FileAction> m_file_actions; // File actions for any other files
+ uint32_t m_resume_count; // How many times do we resume after launching
+};
+
+//----------------------------------------------------------------------
+// ProcessLaunchInfo
+//
+// Describes any information that is required to launch a process.
+//----------------------------------------------------------------------
+
+class ProcessAttachInfo : public ProcessInstanceInfo
+{
+public:
+ ProcessAttachInfo() :
+ ProcessInstanceInfo(),
+ m_plugin_name (),
+ m_resume_count (0),
+ m_wait_for_launch (false)
+ {
+ }
+
+ ProcessAttachInfo (const ProcessLaunchInfo &launch_info) :
+ ProcessInstanceInfo(),
+ m_plugin_name (),
+ m_resume_count (0),
+ m_wait_for_launch (false)
+ {
+ ProcessInfo::operator= (launch_info);
+ SetProcessPluginName (launch_info.GetProcessPluginName());
+ SetResumeCount (launch_info.GetResumeCount());
+ }
+
+ bool
+ GetWaitForLaunch () const
+ {
+ return m_wait_for_launch;
+ }
+
+ void
+ SetWaitForLaunch (bool b)
+ {
+ m_wait_for_launch = b;
+ }
+
+ uint32_t
+ GetResumeCount () const
+ {
+ return m_resume_count;
+ }
+
+ void
+ SetResumeCount (uint32_t c)
+ {
+ m_resume_count = c;
+ }
+
+ const char *
+ GetProcessPluginName () const
+ {
+ if (m_plugin_name.empty())
+ return NULL;
+ return m_plugin_name.c_str();
+ }
+
+ void
+ SetProcessPluginName (const char *plugin)
+ {
+ if (plugin && plugin[0])
+ m_plugin_name.assign (plugin);
+ else
+ m_plugin_name.clear();
+ }
+
+ void
+ Clear ()
+ {
+ ProcessInstanceInfo::Clear();
+ m_plugin_name.clear();
+ m_resume_count = 0;
+ m_wait_for_launch = false;
+ }
+
+ bool
+ ProcessInfoSpecified () const
+ {
+ if (GetExecutableFile())
+ return true;
+ if (GetProcessID() != LLDB_INVALID_PROCESS_ID)
+ return true;
+ if (GetParentProcessID() != LLDB_INVALID_PROCESS_ID)
+ return true;
+ return false;
+ }
+protected:
+ std::string m_plugin_name;
+ uint32_t m_resume_count; // How many times do we resume after launching
+ bool m_wait_for_launch;
};
class ProcessLaunchCommandOptions : public Options
@@ -744,12 +875,12 @@ public:
}
ProcessInstanceInfoMatch (const char *process_name,
- lldb_private::NameMatchType process_name_match_type) :
+ lldb_private::NameMatchType process_name_match_type) :
m_match_info (),
m_name_match_type (process_name_match_type),
m_match_all_users (false)
{
- m_match_info.SetName (process_name);
+ m_match_info.GetExecutableFile().SetFile(process_name, false);
}
ProcessInstanceInfo &
@@ -1316,11 +1447,12 @@ public:
Launch (const ProcessLaunchInfo &launch_info);
//------------------------------------------------------------------
- /// Attach to an existing process using a process ID.
+ /// Attach to an existing process using the process attach info.
///
/// This function is not meant to be overridden by Process
- /// subclasses. It will first call Process::WillAttach (lldb::pid_t)
- /// and if that returns \b true, Process::DoAttach (lldb::pid_t) will
+ /// subclasses. It will first call WillAttach (lldb::pid_t)
+ /// or WillAttach (const char *), and if that returns \b
+ /// true, DoAttach (lldb::pid_t) or DoAttach (const char *) will
/// be called to actually do the attach. If DoAttach returns \b
/// true, then Process::DidAttach() will be called.
///
@@ -1332,28 +1464,8 @@ public:
/// LLDB_INVALID_PROCESS_ID if attaching fails.
//------------------------------------------------------------------
virtual Error
- Attach (lldb::pid_t pid, uint32_t exec_count);
+ Attach (ProcessAttachInfo &attach_info);
- //------------------------------------------------------------------
- /// Attach to an existing process by process name.
- ///
- /// This function is not meant to be overridden by Process
- /// subclasses. It will first call
- /// Process::WillAttach (const char *) and if that returns \b
- /// true, Process::DoAttach (const char *) will be called to
- /// actually do the attach. If DoAttach returns \b true, then
- /// Process::DidAttach() will be called.
- ///
- /// @param[in] process_name
- /// A process name to match against the current process list.
- ///
- /// @return
- /// Returns \a pid if attaching was successful, or
- /// LLDB_INVALID_PROCESS_ID if attaching fails.
- //------------------------------------------------------------------
- virtual Error
- Attach (const char *process_name, bool wait_for_launch);
-
virtual Error
ConnectRemote (const char *remote_url);
diff --git a/lldb/include/lldb/lldb-forward.h b/lldb/include/lldb/lldb-forward.h
index fb23b43e4e8..c75f75fe02d 100644
--- a/lldb/include/lldb/lldb-forward.h
+++ b/lldb/include/lldb/lldb-forward.h
@@ -112,6 +112,7 @@ class NamedOption;
class PathMappingList;
class Platform;
class Process;
+class ProcessAttachInfo;
class ProcessModID;
class ProcessInfo;
class ProcessInstanceInfo;
@@ -128,7 +129,7 @@ class ScriptInterpreter;
#ifndef LLDB_DISABLE_PYTHON
class ScriptInterpreterPython;
struct ScriptSummaryFormat;
-#endif // #ifndef LLDB_DISABLE_PYTHON
+#endif
class SearchFilter;
class Section;
class SectionImpl;
@@ -161,7 +162,7 @@ class SyntheticChildren;
class SyntheticChildrenFrontEnd;
#ifndef LLDB_DISABLE_PYTHON
class SyntheticScriptProvider;
-#endif // #ifndef LLDB_DISABLE_PYTHON
+#endif
class Target;
class TargetList;
class Thread;
diff --git a/lldb/source/API/SBProcess.cpp b/lldb/source/API/SBProcess.cpp
index 66abd086c40..5a98c9f96d6 100644
--- a/lldb/source/API/SBProcess.cpp
+++ b/lldb/source/API/SBProcess.cpp
@@ -169,7 +169,9 @@ SBProcess::RemoteAttachToProcessWithID (lldb::pid_t pid, lldb::SBError& error)
Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
if (m_opaque_sp->GetState() == eStateConnected)
{
- error.SetError (m_opaque_sp->Attach (pid, 0));
+ ProcessAttachInfo attach_info;
+ attach_info.SetProcessID (pid);
+ error.SetError (m_opaque_sp->Attach (attach_info));
}
else
{
diff --git a/lldb/source/API/SBTarget.cpp b/lldb/source/API/SBTarget.cpp
index 58d89b197ae..c393635c3c6 100644
--- a/lldb/source/API/SBTarget.cpp
+++ b/lldb/source/API/SBTarget.cpp
@@ -337,7 +337,9 @@ SBTarget::AttachToProcessWithID
if (sb_process.IsValid())
{
- error.SetError (sb_process->Attach (pid, 0));
+ ProcessAttachInfo attach_info;
+ attach_info.SetProcessID (pid);
+ error.SetError (sb_process->Attach (attach_info));
// If we are doing synchronous mode, then wait for the
// process to stop!
if (m_opaque_sp->GetDebugger().GetAsyncExecution () == false)
@@ -409,7 +411,10 @@ SBTarget::AttachToProcessWithName
if (sb_process.IsValid())
{
- error.SetError (sb_process->Attach (name, wait_for));
+ ProcessAttachInfo attach_info;
+ attach_info.GetExecutableFile().SetFile(name, false);
+ attach_info.SetWaitForLaunch(wait_for);
+ error.SetError (sb_process->Attach (attach_info));
// If we are doing synchronous mode, then wait for the
// process to stop!
if (m_opaque_sp->GetDebugger().GetAsyncExecution () == false)
diff --git a/lldb/source/Commands/CommandObjectPlatform.cpp b/lldb/source/Commands/CommandObjectPlatform.cpp
index e2136d32cac..c9f776ed7ee 100644
--- a/lldb/source/Commands/CommandObjectPlatform.cpp
+++ b/lldb/source/Commands/CommandObjectPlatform.cpp
@@ -653,27 +653,27 @@ protected:
break;
case 'n':
- match_info.GetProcessInfo().SetName (option_arg);
+ match_info.GetProcessInfo().GetExecutableFile().SetFile (option_arg, false);
match_info.SetNameMatchType (eNameMatchEquals);
break;
case 'e':
- match_info.GetProcessInfo().SetName (option_arg);
+ match_info.GetProcessInfo().GetExecutableFile().SetFile (option_arg, false);
match_info.SetNameMatchType (eNameMatchEndsWith);
break;
case 's':
- match_info.GetProcessInfo().SetName (option_arg);
+ match_info.GetProcessInfo().GetExecutableFile().SetFile (option_arg, false);
match_info.SetNameMatchType (eNameMatchStartsWith);
break;
case 'c':
- match_info.GetProcessInfo().SetName (option_arg);
+ match_info.GetProcessInfo().GetExecutableFile().SetFile (option_arg, false);
match_info.SetNameMatchType (eNameMatchContains);
break;
case 'r':
- match_info.GetProcessInfo().SetName (option_arg);
+ match_info.GetProcessInfo().GetExecutableFile().SetFile (option_arg, false);
match_info.SetNameMatchType (eNameMatchRegularExpression);
break;
diff --git a/lldb/source/Commands/CommandObjectProcess.cpp b/lldb/source/Commands/CommandObjectProcess.cpp
index e7d392da030..e048182d04b 100644
--- a/lldb/source/Commands/CommandObjectProcess.cpp
+++ b/lldb/source/Commands/CommandObjectProcess.cpp
@@ -212,12 +212,32 @@ public:
}
}
- if (launch_args.GetArgumentCount() > 0)
+ if (launch_args.GetArgumentCount() == 0)
+ {
+ const Args &process_args = target->GetRunArguments();
+ if (process_args.GetArgumentCount() > 0)
+ m_options.launch_info.GetArguments().AppendArguments (process_args);
+ }
+ else
{
m_options.launch_info.GetArguments().AppendArguments (launch_args);
}
-
+ if (target->GetDisableASLR())
+ m_options.launch_info.GetFlags().Set (eLaunchFlagDisableASLR);
+
+ if (target->GetDisableSTDIO())
+ m_options.launch_info.GetFlags().Set (eLaunchFlagDisableSTDIO);
+
+ m_options.launch_info.GetFlags().Set (eLaunchFlagDebug);
+
+ Args environment;
+ target->GetEnvironmentAsArgs (environment);
+ if (environment.GetArgumentCount() > 0)
+ m_options.launch_info.GetEnvironmentEntries ().AppendArguments (environment);
+
+ m_options.launch_info.FinalizeFileActions (target);
+
if (state == eStateConnected)
{
if (m_options.launch_info.GetFlags().Test (eLaunchFlagLaunchInTTY))
@@ -228,78 +248,18 @@ public:
}
else
{
- const char *plugin_name = m_options.launch_info.GetProcessPluginName();
-
- if (m_options.launch_info.GetFlags().Test (eLaunchFlagLaunchInTTY))
- {
+ if (!m_options.launch_info.GetArchitecture().IsValid())
m_options.launch_info.GetArchitecture() = target->GetArchitecture();
- process = target->GetPlatform()->DebugProcess (m_options.launch_info,
- debugger,
- target,
- debugger.GetListener(),
- error).get();
- }
- else
- {
- process = target->CreateProcess (debugger.GetListener(), plugin_name).get();
-
- if (launch_args.GetArgumentCount() == 0)
- {
- const Args &process_args = target->GetRunArguments();
- if (process_args.GetArgumentCount() > 0)
- m_options.launch_info.GetArguments().AppendArguments (process_args);
- }
-
- Args environment;
- target->GetEnvironmentAsArgs (environment);
- m_options.launch_info.GetEnvironmentEntries ().AppendArguments (environment);
-
- if (target->GetDisableASLR())
- m_options.launch_info.GetFlags().Set (eLaunchFlagDisableASLR);
-
- if (m_options.launch_info.GetNumFileActions() == 0)
- {
- // Only use the settings value if the user hasn't specified any options that would override it.
- if (target->GetDisableSTDIO())
- m_options.launch_info.GetFlags().Set (eLaunchFlagDisableSTDIO);
-
- const char *path;
- path = target->GetStandardErrorPath();
- if (path)
- {
- ProcessLaunchInfo::FileAction file_action;
- const bool read = true;
- const bool write = true;
- if (file_action.Open(STDERR_FILENO, path, read, write))
- m_options.launch_info.AppendFileAction (file_action);
- }
- path = target->GetStandardInputPath();
- if (path)
- {
- ProcessLaunchInfo::FileAction file_action;
- const bool read = true;
- const bool write = false;
- if (file_action.Open(STDIN_FILENO, path, read, write))
- m_options.launch_info.AppendFileAction (file_action);
- }
+ process = target->GetPlatform()->DebugProcess (m_options.launch_info,
+ debugger,
+ target,
+ debugger.GetListener(),
+ error).get();
- path = target->GetStandardOutputPath();
- if (path)
- {
- ProcessLaunchInfo::FileAction file_action;
- const bool read = false;
- const bool write = true;
- if (file_action.Open(STDOUT_FILENO, path, read, write))
- m_options.launch_info.AppendFileAction (file_action);
- }
- }
- error = process->Launch (m_options.launch_info);
- }
if (process == NULL)
{
- result.AppendErrorWithFormat ("Failed to find a process plugin for executable.\n");
- result.SetStatus (eReturnStatusFailed);
+ result.SetError (error, "failed to launch or debug process");
return false;
}
}
@@ -326,7 +286,7 @@ public:
state = process->WaitForProcessToStop (NULL);
if (!StateIsStoppedState(state))
{
- result.AppendErrorWithFormat ("Process isn't stopped: %s", StateAsCString(state));
+ result.AppendErrorWithFormat ("process isn't stopped: %s", StateAsCString(state));
}
result.SetDidChangeProcessState (true);
result.SetStatus (eReturnStatusSuccessFinishResult);
@@ -338,13 +298,13 @@ public:
}
else
{
- result.AppendErrorWithFormat ("Process resume at entry point failed: %s", error.AsCString());
+ result.AppendErrorWithFormat ("process resume at entry point failed: %s", error.AsCString());
result.SetStatus (eReturnStatusFailed);
}
}
else
{
- result.AppendErrorWithFormat ("Initial process state wasn't stopped: %s", StateAsCString(state));
+ result.AppendErrorWithFormat ("initial process state wasn't stopped: %s", StateAsCString(state));
result.SetStatus (eReturnStatusFailed);
}
}
@@ -423,23 +383,29 @@ public:
switch (short_option)
{
case 'p':
- pid = Args::StringToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success);
- if (!success || pid == LLDB_INVALID_PROCESS_ID)
{
- error.SetErrorStringWithFormat("invalid process ID '%s'", option_arg);
+ lldb::pid_t pid = Args::StringToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success);
+ if (!success || pid == LLDB_INVALID_PROCESS_ID)
+ {
+ error.SetErrorStringWithFormat("invalid process ID '%s'", option_arg);
+ }
+ else
+ {
+ attach_info.SetProcessID (pid);
+ }
}
break;
case 'P':
- plugin_name = option_arg;
+ attach_info.SetProcessPluginName (option_arg);
break;
case 'n':
- name.assign(option_arg);
+ attach_info.GetExecutableFile().SetFile(option_arg, false);
break;
case 'w':
- waitfor = true;
+ attach_info.SetWaitForLaunch(true);
break;
default:
@@ -452,9 +418,7 @@ public:
void
OptionParsingStarting ()
{
- pid = LLDB_INVALID_PROCESS_ID;
- name.clear();
- waitfor = false;
+ attach_info.Clear();
}
const OptionDefinition*
@@ -497,7 +461,7 @@ public:
ProcessInstanceInfoMatch match_info;
if (partial_name)
{
- match_info.GetProcessInfo().SetName(partial_name);
+ match_info.GetProcessInfo().GetExecutableFile().SetFile(partial_name, false);
match_info.SetNameMatchType(eNameMatchStartsWith);
}
platform_sp->FindProcesses (match_info, process_infos);
@@ -522,10 +486,7 @@ public:
// Instance variables to hold the values for command options.
- lldb::pid_t pid;
- std::string plugin_name;
- std::string name;
- bool waitfor;
+ ProcessAttachInfo attach_info;
};
CommandObjectProcessAttach (CommandInterpreter &interpreter) :
@@ -601,55 +562,37 @@ public:
{
if (state != eStateConnected)
{
- const char *plugin_name = NULL;
-
- if (!m_options.plugin_name.empty())
- plugin_name = m_options.plugin_name.c_str();
-
+ const char *plugin_name = m_options.attach_info.GetProcessPluginName();
process = target->CreateProcess (m_interpreter.GetDebugger().GetListener(), plugin_name).get();
}
if (process)
{
Error error;
- int attach_pid = m_options.pid;
-
- const char *wait_name = NULL;
-
- if (m_options.name.empty())
+ // 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->GetFileSpec().GetFilename();
+
+ if (!m_options.attach_info.ProcessInfoSpecified ())
{
- wait_name = old_exec_module_sp->GetFileSpec().GetFilename().AsCString();
+ error.SetErrorString ("no process specified, create a target with a file, or specify the --pid or --name command option");
}
}
- else
- {
- wait_name = m_options.name.c_str();
- }
-
- // If we are waiting for a process with this name to show up, do that first.
- if (m_options.waitfor)
- {
-
- if (wait_name == NULL)
- {
- result.AppendError("Invalid arguments: must have a file loaded or supply a process name with the waitfor option.\n");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- result.AppendMessageWithFormat("Waiting to attach to a process named \"%s\".\n", wait_name);
- error = process->Attach (wait_name, m_options.waitfor);
+ if (error.Success())
+ {
+ error = process->Attach (m_options.attach_info);
+
if (error.Success())
{
result.SetStatus (eReturnStatusSuccessContinuingNoResult);
}
else
{
- result.AppendErrorWithFormat ("Waiting for a process to launch named '%s': %s\n",
- wait_name,
- error.AsCString());
+ result.AppendErrorWithFormat ("attach failed: %s\n", error.AsCString());
result.SetStatus (eReturnStatusFailed);
return false;
}
@@ -658,70 +601,11 @@ public:
// FIXME: in the async case it will now be possible to get to the command
// interpreter with a state eStateAttaching. Make sure we handle that correctly.
StateType state = process->WaitForProcessToStop (NULL);
-
+
result.SetDidChangeProcessState (true);
result.AppendMessageWithFormat ("Process %llu %s\n", process->GetID(), StateAsCString (state));
result.SetStatus (eReturnStatusSuccessFinishNoResult);
}
- else
- {
- // If the process was specified by name look it up, so we can warn if there are multiple
- // processes with this pid.
-
- if (attach_pid == LLDB_INVALID_PROCESS_ID && wait_name != NULL)
- {
- ProcessInstanceInfoList process_infos;
- PlatformSP platform_sp (m_interpreter.GetPlatform (true));
- if (platform_sp)
- {
- ProcessInstanceInfoMatch match_info (wait_name, eNameMatchEquals);
- platform_sp->FindProcesses (match_info, process_infos);
- }
- if (process_infos.GetSize() > 1)
- {
- result.AppendErrorWithFormat("More than one process named %s\n", wait_name);
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- else if (process_infos.GetSize() == 0)
- {
- result.AppendErrorWithFormat("Could not find a process named %s\n", wait_name);
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- else
- {
- attach_pid = process_infos.GetProcessIDAtIndex (0);
- }
- }
-
- if (attach_pid != LLDB_INVALID_PROCESS_ID)
- {
- error = process->Attach (attach_pid, 0);
- if (error.Success())
- {
- result.SetStatus (eReturnStatusSuccessContinuingNoResult);
- }
- else
- {
- result.AppendErrorWithFormat ("Attaching to process %i failed: %s.\n",
- attach_pid,
- error.AsCString());
- result.SetStatus (eReturnStatusFailed);
- }
- StateType state = process->WaitForProcessToStop (NULL);
-
- result.SetDidChangeProcessState (true);
- result.AppendMessageWithFormat ("Process %llu %s\n", process->GetID(), StateAsCString (state));
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
- }
- else
- {
- result.AppendErrorWithFormat ("No PID specified for attach\n");
- result.SetStatus (eReturnStatusFailed);
-
- }
- }
}
}
diff --git a/lldb/source/Host/macosx/Host.mm b/lldb/source/Host/macosx/Host.mm
index 048555a4e9c..529525d6ea6 100644
--- a/lldb/source/Host/macosx/Host.mm
+++ b/lldb/source/Host/macosx/Host.mm
@@ -59,6 +59,12 @@
#define _POSIX_SPAWN_DISABLE_ASLR 0x0100
#endif
+extern "C"
+{
+ int __pthread_chdir(const char *path);
+ int __pthread_fchdir (int fildes);
+}
+
using namespace lldb;
using namespace lldb_private;
@@ -431,25 +437,6 @@ tell application \"Terminal\"\n\
do script the_shell_script\n\
end tell\n";
-static const char *
-GetShellSafeArgument (const char *unsafe_arg, std::string &safe_arg)
-{
- safe_arg.assign (unsafe_arg);
- size_t prev_pos = 0;
- while (prev_pos < safe_arg.size())
- {
- // Escape spaces and quotes
- size_t pos = safe_arg.find_first_of(" '\"", prev_pos);
- if (pos != std::string::npos)
- {
- safe_arg.insert (pos, 1, '\\');
- prev_pos = pos + 2;
- }
- else
- break;
- }
- return safe_arg.c_str();
-}
static Error
LaunchInNewTerminalWithAppleScript (const char *exe_path, ProcessLaunchInfo &launch_info)
@@ -499,44 +486,22 @@ LaunchInNewTerminalWithAppleScript (const char *exe_path, ProcessLaunchInfo &lau
if (launch_info.GetFlags().Test (eLaunchFlagDisableASLR))
command.PutCString(" --disable-aslr");
- if (launch_info.GetFlags().Test (eLaunchFlagLaunchInShell))
+ command.PutCString(" -- ");
+
+ const char **argv = launch_info.GetArguments().GetConstArgumentVector ();
+ if (argv)
{
- const char *shell_executable = "/bin/bash"; //getenv("SHELL");
- std::string safe_arg;
- if (launch_info.GetArchitecture().IsValid())
- command.Printf(" -- %s -c 'exec /usr/bin/arch -arch %s", shell_executable, launch_info.GetArchitecture().GetArchitectureName());
- else
- command.Printf(" -- %s -c 'exec ", shell_executable);
- const char **argv = launch_info.GetArguments().GetConstArgumentVector ();
- if (argv)
+ for (size_t i=0; argv[i] != NULL; ++i)
{
- for (size_t i=0; argv[i] != NULL; ++i)
- {
- const char *arg = GetShellSafeArgument (i == 0 ? exe_path : argv[i], safe_arg);
- command.Printf(" %s", arg);
- }
+ if (i==0)
+ command.Printf(" '%s'", exe_path);
+ else
+ command.Printf(" '%s'", argv[i]);
}
- command.PutChar('\'');
}
else
{
- command.PutCString(" -- ");
-
- const char **argv = launch_info.GetArguments().GetConstArgumentVector ();
- if (argv)
- {
- for (size_t i=0; argv[i] != NULL; ++i)
- {
- if (i==0)
- command.Printf(" '%s'", exe_path);
- else
- command.Printf(" '%s'", argv[i]);
- }
- }
- else
- {
- command.Printf(" '%s'", exe_path);
- }
+ command.Printf(" '%s'", exe_path);
}
command.PutCString (" ; echo Process exited with status $?");
@@ -1007,11 +972,11 @@ GetMacOSXProcessName (const ProcessInstanceInfoMatch *match_info_ptr,
match_info_ptr->GetNameMatchType(),
match_info_ptr->GetProcessInfo().GetName()))
{
- process_info.SetName (process_name);
+ process_info.GetExecutableFile().SetFile (process_name, false);
return true;
}
}
- process_info.SetName (NULL);
+ process_info.GetExecutableFile().Clear();
return false;
}
@@ -1306,6 +1271,11 @@ Host::LaunchProcess (ProcessLaunchInfo &launch_info)
if (launch_info.GetFlags().Test (eLaunchFlagDisableASLR))
flags |= _POSIX_SPAWN_DISABLE_ASLR; // Darwin specific posix_spawn flag
+//#ifdef POSIX_SPAWN_CLOEXEC_DEFAULT
+// // Close all files exception those with file actions if this is supported.
+// flags |= POSIX_SPAWN_CLOEXEC_DEFAULT;
+//#endif
+
error.SetError( ::posix_spawnattr_setflags (&attr, flags), eErrorTypePOSIX);
if (error.Fail() || log)
error.PutToLog(log.get(), "::posix_spawnattr_setflags ( &attr, flags=0x%8.8x )", flags);
@@ -1347,6 +1317,13 @@ Host::LaunchProcess (ProcessLaunchInfo &launch_info)
}
+ const char *working_dir = launch_info.GetWorkingDirectory();
+ if (working_dir)
+ {
+ // No more thread specific current working directory
+ __pthread_chdir (working_dir);
+ }
+
const size_t num_file_actions = launch_info.GetNumFileActions ();
if (num_file_actions > 0)
{
@@ -1410,6 +1387,12 @@ Host::LaunchProcess (ProcessLaunchInfo &launch_info)
envp);
}
+ if (working_dir)
+ {
+ // No more thread specific current working directory
+ __pthread_fchdir (-1);
+ }
+
if (pid != LLDB_INVALID_PROCESS_ID)
{
// If all went well, then set the process ID into the launch info
diff --git a/lldb/source/Interpreter/Args.cpp b/lldb/source/Interpreter/Args.cpp
index 50b43b1678c..f32b25c9127 100644
--- a/lldb/source/Interpreter/Args.cpp
+++ b/lldb/source/Interpreter/Args.cpp
@@ -864,6 +864,26 @@ Args::StringToVersion (const char *s, uint32_t &major, uint32_t &minor, uint32_t
return 0;
}
+const char *
+Args::GetShellSafeArgument (const char *unsafe_arg, std::string &safe_arg)
+{
+ safe_arg.assign (unsafe_arg);
+ size_t prev_pos = 0;
+ while (prev_pos < safe_arg.size())
+ {
+ // Escape spaces and quotes
+ size_t pos = safe_arg.find_first_of(" '\"", prev_pos);
+ if (pos != std::string::npos)
+ {
+ safe_arg.insert (pos, 1, '\\');
+ prev_pos = pos + 2;
+ }
+ else
+ break;
+ }
+ return safe_arg.c_str();
+}
+
int32_t
Args::StringToOptionEnum (const char *s, OptionEnumValueElement *enum_values, int32_t fail_value, Error &error)
diff --git a/lldb/source/Interpreter/CommandReturnObject.cpp b/lldb/source/Interpreter/CommandReturnObject.cpp
index eb6fae4ce1b..51e6ee6e5fe 100644
--- a/lldb/source/Interpreter/CommandReturnObject.cpp
+++ b/lldb/source/Interpreter/CommandReturnObject.cpp
@@ -13,6 +13,7 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
+#include "lldb/Core/Error.h"
#include "lldb/Core/StreamString.h"
using namespace lldb;
@@ -134,6 +135,15 @@ CommandReturnObject::AppendError (const char *in_string, int len)
GetErrorStream().Printf ("error: %*.*s\n", len, len, in_string);
}
+void
+CommandReturnObject::SetError (const Error &error, const char *fallback_error_cstr)
+{
+ const char *error_cstr = error.AsCString();
+ if (error_cstr == NULL)
+ error_cstr = fallback_error_cstr;
+ AppendError (error_cstr);
+ SetStatus (eReturnStatusFailed);
+}
// Similar to AppendError, but do not prepend 'Error: ' to message, and
// don't append "\n" to the end of it.
diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
index 8baaefc929f..408a57f391a 100644
--- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
+++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
@@ -395,8 +395,15 @@ Error
PlatformDarwin::LaunchProcess (ProcessLaunchInfo &launch_info)
{
Error error;
+
if (IsHost())
{
+ if (launch_info.GetFlags().Test (eLaunchFlagLaunchInShell))
+ {
+ const bool is_localhost = true;
+ if (!launch_info.ConvertArgumentsForLaunchingInShell (error, is_localhost))
+ return error;
+ }
error = Platform::LaunchProcess (launch_info);
}
else
@@ -410,13 +417,14 @@ PlatformDarwin::LaunchProcess (ProcessLaunchInfo &launch_info)
}
lldb::ProcessSP
-PlatformDarwin::Attach (lldb::pid_t pid,
+PlatformDarwin::Attach (ProcessAttachInfo &attach_info,
Debugger &debugger,
Target *target,
Listener &listener,
Error &error)
{
lldb::ProcessSP process_sp;
+
if (IsHost())
{
if (target == NULL)
@@ -438,18 +446,17 @@ PlatformDarwin::Attach (lldb::pid_t pid,
if (target && error.Success())
{
debugger.GetTargetList().SetSelectedTarget(target);
- // The darwin always currently uses the GDB remote debugger plug-in
- // so even when debugging locally we are debugging remotely!
- process_sp = target->CreateProcess (listener, "gdb-remote");
+
+ process_sp = target->CreateProcess (listener, attach_info.GetProcessPluginName());
if (process_sp)
- error = process_sp->Attach (pid, 2);
+ error = process_sp->Attach (attach_info);
}
}
else
{
if (m_remote_platform_sp)
- process_sp = m_remote_platform_sp->Attach (pid, debugger, target, listener, error);
+ process_sp = m_remote_platform_sp->Attach (attach_info, debugger, target, listener, error);
else
error.SetErrorString ("the platform is not currently connected");
}
diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h
index 9b3e771193e..5ed533da3a3 100644
--- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h
+++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h
@@ -79,7 +79,7 @@ public:
LaunchProcess (lldb_private::ProcessLaunchInfo &launch_info);
virtual lldb::ProcessSP
- Attach (lldb::pid_t pid,
+ Attach (lldb_private::ProcessAttachInfo &attach_info,
lldb_private::Debugger &debugger,
lldb_private::Target *target, // Can be NULL, if NULL create a new target, else use existing one
lldb_private::Listener &listener,
diff --git a/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp b/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
index 69fa4487e3e..387737b7ab6 100644
--- a/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
+++ b/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
@@ -337,7 +337,7 @@ PlatformRemoteGDBServer::LaunchProcess (ProcessLaunchInfo &launch_info)
}
lldb::ProcessSP
-PlatformRemoteGDBServer::Attach (lldb::pid_t pid,
+PlatformRemoteGDBServer::Attach (lldb_private::ProcessAttachInfo &attach_info,
Debugger &debugger,
Target *target, // Can be NULL, if NULL create a new target, else use existing one
Listener &listener,
@@ -391,7 +391,7 @@ PlatformRemoteGDBServer::Attach (lldb::pid_t pid,
assert (connect_url_len < sizeof(connect_url));
error = process_sp->ConnectRemote (connect_url);
if (error.Success())
- error = process_sp->Attach(pid, 0);
+ error = process_sp->Attach(attach_info);
}
}
}
diff --git a/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h b/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
index 36c48c24b60..e141f7fc080 100644
--- a/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
+++ b/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
@@ -94,7 +94,7 @@ public:
LaunchProcess (lldb_private::ProcessLaunchInfo &launch_info);
virtual lldb::ProcessSP
- Attach (lldb::pid_t pid,
+ Attach (lldb_private::ProcessAttachInfo &attach_info,
lldb_private::Debugger &debugger,
lldb_private::Target *target, // Can be NULL, if NULL create a new target, else use existing one
lldb_private::Listener &listener,
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index 85f56dd3ffb..5dd4dc68027 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -1243,7 +1243,7 @@ GDBRemoteCommunicationClient::DecodeProcessInfoResponse (StringExtractorGDBRemot
extractor.GetStringRef().swap(value);
extractor.SetFilePos(0);
extractor.GetHexByteString (value);
- process_info.SetName (value.c_str());
+ process_info.GetExecutableFile().SetFile (value.c_str(), false);
}
}
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
index 9712d6f2ccd..2fbac25c933 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
@@ -335,7 +335,7 @@ GDBRemoteCommunicationServer::Handle_qfProcessInfo (StringExtractorGDBRemote &pa
StringExtractor extractor;
extractor.GetStringRef().swap(value);
extractor.GetHexByteString (value);
- match_info.GetProcessInfo().SetName (value.c_str());
+ match_info.GetProcessInfo().GetExecutableFile().SetFile(value.c_str(), false);
}
else if (key.compare("name_match") == 0)
{
diff --git a/lldb/source/Target/Platform.cpp b/lldb/source/Target/Platform.cpp
index 0213ac61485..3b780428836 100644
--- a/lldb/source/Target/Platform.cpp
+++ b/lldb/source/Target/Platform.cpp
@@ -577,16 +577,10 @@ Platform::DebugProcess (ProcessLaunchInfo &launch_info,
error = LaunchProcess (launch_info);
if (error.Success())
{
- lldb::pid_t pid = launch_info.GetProcessID();
- if (pid != LLDB_INVALID_PROCESS_ID)
+ if (launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID)
{
- process_sp = Attach (pid, debugger, target, listener, error);
-
-// if (process_sp)
-// {
-// if (launch_info.GetFlags().IsClear (eLaunchFlagStopAtEntry))
-// process_sp->Resume();
-// }
+ ProcessAttachInfo attach_info (launch_info);
+ process_sp = Attach (attach_info, debugger, target, listener, error);
}
}
return process_sp;
diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp
index 6ee9dbf85de..e70788e93ac 100644
--- a/lldb/source/Target/Process.cpp
+++ b/lldb/source/Target/Process.cpp
@@ -251,7 +251,7 @@ ProcessInfo::SetArguments (const Args& args,
}
void
-ProcessLaunchInfo::FinalizeFileActions (Target *target, Process *process)
+ProcessLaunchInfo::FinalizeFileActions (Target *target)
{
// If notthing was specified, then check the process for any default
// settings that were set with "settings set"
@@ -304,6 +304,87 @@ ProcessLaunchInfo::FinalizeFileActions (Target *target, Process *process)
}
}
+
+bool
+ProcessLaunchInfo::ConvertArgumentsForLaunchingInShell (Error &error, bool localhost)
+{
+ error.Clear();
+
+ if (GetFlags().Test (eLaunchFlagLaunchInShell))
+ {
+ const char *shell_executable = GetShell();
+ if (shell_executable)
+ {
+ char shell_resolved_path[PATH_MAX];
+
+ if (localhost)
+ {
+ FileSpec shell_filespec (shell_executable, true);
+
+ if (!shell_filespec.Exists())
+ {
+ // Resolve the path in case we just got "bash", "sh" or "tcsh"
+ if (!shell_filespec.ResolveExecutableLocation ())
+ {
+ error.SetErrorStringWithFormat("invalid shell path '%s'", shell_executable);
+ return false;
+ }
+ }
+ shell_filespec.GetPath (shell_resolved_path, sizeof(shell_resolved_path));
+ shell_executable = shell_resolved_path;
+ }
+
+ Args shell_arguments;
+ std::string safe_arg;
+ shell_arguments.AppendArgument (shell_executable);
+ StreamString shell_command;
+ shell_arguments.AppendArgument ("-c");
+ shell_command.PutCString ("exec");
+ if (GetArchitecture().IsValid())
+ {
+ shell_command.Printf(" /usr/bin/arch -arch %s", GetArchitecture().GetArchitectureName());
+ // Set the resume count to 2:
+ // 1 - stop in shell
+ // 2 - stop in /usr/bin/arch
+ // 3 - then we will stop in our program
+ SetResumeCount(2);
+ }
+ else
+ {
+ // Set the resume count to 1:
+ // 1 - stop in shell
+ // 2 - then we will stop in our program
+ SetResumeCount(1);
+ }
+
+ const char **argv = GetArguments().GetConstArgumentVector ();
+ if (argv)
+ {
+ for (size_t i=0; argv[i] != NULL; ++i)
+ {
+ const char *arg = Args::GetShellSafeArgument (argv[i], safe_arg);
+ shell_command.Printf(" %s", arg);
+ }
+ }
+ shell_arguments.AppendArgument (shell_command.GetString().c_str());
+
+ m_executable.SetFile(shell_executable, false);
+ m_arguments = shell_arguments;
+ return true;
+ }
+ else
+ {
+ error.SetErrorString ("invalid shell path");
+ }
+ }
+ else
+ {
+ error.SetErrorString ("not launching in shell");
+ }
+ return false;
+}
+
+
bool
ProcessLaunchInfo::FileAction::Open (int fd, const char *path, bool read, bool write)
{
@@ -312,11 +393,11 @@ ProcessLaunchInfo::FileAction::Open (int fd, const char *path, bool read, bool w
m_action = eFileActionOpen;
m_fd = fd;
if (read && write)
- m_arg = O_RDWR;
+ m_arg = O_NOCTTY | O_CREAT | O_RDWR;
else if (read)
- m_arg = O_RDONLY;
+ m_arg = O_NOCTTY | O_RDONLY;
else
- m_arg = O_WRONLY;
+ m_arg = O_NOCTTY | O_CREAT | O_WRONLY;
m_path.assign (path);
return true;
}
@@ -404,8 +485,12 @@ ProcessLaunchInfo::FileAction::AddPosixSpawnFileAction (posix_spawn_file_actions
else
{
int oflag = info->m_arg;
+
mode_t mode = 0;
+ if (oflag & O_CREAT)
+ mode = 0640;
+
error.SetError (::posix_spawn_file_actions_addopen (file_actions,
info->m_fd,
info->m_path.c_str(),
@@ -496,7 +581,10 @@ ProcessLaunchCommandOptions::SetOptionValue (uint32_t option_idx, const char *op
break;
case 'c':
- launch_info.GetFlags().Set (eLaunchFlagLaunchInShell);
+ if (option_arg && option_arg[0])
+ launch_info.SetShell (option_arg);
+ else
+ launch_info.SetShell ("/bin/bash");
break;
case 'v':
@@ -520,7 +608,7 @@ ProcessLaunchCommandOptions::g_option_table[] =
{ LLDB_OPT_SET_ALL, false, "working-dir", 'w', required_argument, NULL, 0, eArgTypePath, "Set the current working directory to <path> when running the inferior."},
{ LLDB_OPT_SET_ALL, false, "arch", 'a', required_argument, NULL, 0, eArgTypeArchitecture, "Set the architecture for the process to launch when ambiguous."},
{ LLDB_OPT_SET_ALL, false, "environment", 'v', required_argument, NULL, 0, eArgTypeNone, "Specify an environment variable name/value stirng (--environement NAME=VALUE). Can be specified multiple times for subsequent environment entries."},
-{ LLDB_OPT_SET_ALL, false, "shell", 'c', no_argument, NULL, 0, eArgTypeNone, "Run the process in a shell (not supported on all platforms)."},
+{ LLDB_OPT_SET_ALL, false, "shell", 'c', optional_argument, NULL, 0, eArgTypePath, "Run the process in a shell (not supported on all platforms)."},
{ LLDB_OPT_SET_1 , false, "stdin", 'i', required_argument, NULL, 0, eArgTypePath, "Redirect stdin for the process to <path>."},
{ LLDB_OPT_SET_1 , false, "stdout", 'o', required_argument, NULL, 0, eArgTypePath, "Redirect stdout for the process to <path>."},
@@ -2229,91 +2317,103 @@ Process::AttachCompletionHandler::GetExitString ()
}
Error
-Process::Attach (lldb::pid_t attach_pid, uint32_t exec_count)
+Process::Attach (ProcessAttachInfo &attach_info)
{
-
m_abi_sp.reset();
m_process_input_reader.reset();
-
m_dyld_ap.reset();
m_os_ap.reset();
-
- Error error (WillAttachToProcessWithID(attach_pid));
- if (error.Success())
- {
- SetPublicState (eStateAttaching);
-
- error = DoAttachToProcessWithID (attach_pid);
- if (error.Success())
- {
-
- SetNextEventAction(new Process::AttachCompletionHandler(this, exec_count));
- StartPrivateStateThread();
- }
- else
- {
- if (GetID() != LLDB_INVALID_PROCESS_ID)
- {
- SetID (LLDB_INVALID_PROCESS_ID);
- const char *error_string = error.AsCString();
- if (error_string == NULL)
- error_string = "attach failed";
-
- SetExitStatus(-1, error_string);
- }
- }
- }
- return error;
-}
-
-Error
-Process::Attach (const char *process_name, bool wait_for_launch)
-{
- m_abi_sp.reset();
- m_process_input_reader.reset();
- // Find the process and its architecture. Make sure it matches the architecture
- // of the current Target, and if not adjust it.
+ lldb::pid_t attach_pid = attach_info.GetProcessID();
Error error;
-
- if (!wait_for_launch)
+ if (attach_pid == LLDB_INVALID_PROCESS_ID)
{
- ProcessInstanceInfoList process_infos;
- PlatformSP platform_sp (m_target.GetPlatform ());
- assert (platform_sp.get());
+ char process_name[PATH_MAX];
- if (platform_sp)
+ if (attach_info.GetExecutableFile().GetPath (process_name, sizeof(process_name)))
{
- ProcessInstanceInfoMatch match_info;
- match_info.GetProcessInfo().SetName(process_name);
- match_info.SetNameMatchType (eNameMatchEquals);
- platform_sp->FindProcesses (match_info, process_infos);
- if (process_infos.GetSize() > 1)
+ const bool wait_for_launch = attach_info.GetWaitForLaunch();
+
+ if (wait_for_launch)
{
- error.SetErrorStringWithFormat ("more than one process named %s", process_name);
+ error = WillAttachToProcessWithName(process_name, wait_for_launch);
+ if (error.Success())
+ {
+ SetPublicState (eStateAttaching);
+ error = DoAttachToProcessWithName (process_name, wait_for_launch);
+ if (error.Fail())
+ {
+ if (GetID() != LLDB_INVALID_PROCESS_ID)
+ {
+ SetID (LLDB_INVALID_PROCESS_ID);
+ if (error.AsCString() == NULL)
+ error.SetErrorString("attach failed");
+
+ SetExitStatus(-1, error.AsCString());
+ }
+ }
+ else
+ {
+ SetNextEventAction(new Process::AttachCompletionHandler(this, attach_info.GetResumeCount()));
+ StartPrivateStateThread();
+ }
+ return error;
+ }
}
- else if (process_infos.GetSize() == 0)
+ else
{
- error.SetErrorStringWithFormat ("could not find a process named %s", process_name);
+ ProcessInstanceInfoList process_infos;
+ PlatformSP platform_sp (m_target.GetPlatform ());
+
+ if (platform_sp)
+ {
+ ProcessInstanceInfoMatch match_info;
+ match_info.GetProcessInfo() = attach_info;
+ match_info.SetNameMatchType (eNameMatchEquals);
+ platform_sp->FindProcesses (match_info, process_infos);
+ const uint32_t num_matches = process_infos.GetSize();
+ if (num_matches == 1)
+ {
+ attach_pid = process_infos.GetProcessIDAtIndex(0);
+ // Fall through and attach using the above process ID
+ }
+ else
+ {
+ match_info.GetProcessInfo().GetExecutableFile().GetPath (process_name, sizeof(process_name));
+ if (num_matches > 1)
+ error.SetErrorStringWithFormat ("more than one process named %s", process_name);
+ else
+ error.SetErrorStringWithFormat ("could not find a process named %s", process_name);
+ }
+ }
+ else
+ {
+ error.SetErrorString ("invalid platform, can't find processes by name");
+ return error;
+ }
}
}
else
- {
- error.SetErrorString ("invalid platform");
+ {
+ error.SetErrorString ("invalid process name");
}
}
-
- if (error.Success())
+
+ if (attach_pid != LLDB_INVALID_PROCESS_ID)
{
- m_dyld_ap.reset();
- m_os_ap.reset();
-
- error = WillAttachToProcessWithName(process_name, wait_for_launch);
+ error = WillAttachToProcessWithID(attach_pid);
if (error.Success())
{
SetPublicState (eStateAttaching);
- error = DoAttachToProcessWithName (process_name, wait_for_launch);
- if (error.Fail())
+
+ error = DoAttachToProcessWithID (attach_pid);
+ if (error.Success())
+ {
+
+ SetNextEventAction(new Process::AttachCompletionHandler(this, attach_info.GetResumeCount()));
+ StartPrivateStateThread();
+ }
+ else
{
if (GetID() != LLDB_INVALID_PROCESS_ID)
{
@@ -2325,16 +2425,80 @@ Process::Attach (const char *process_name, bool wait_for_launch)
SetExitStatus(-1, error_string);
}
}
- else
- {
- SetNextEventAction(new Process::AttachCompletionHandler(this, 0));
- StartPrivateStateThread();
- }
}
}
return error;
}
+//Error
+//Process::Attach (const char *process_name, bool wait_for_launch)
+//{
+// m_abi_sp.reset();
+// m_process_input_reader.reset();
+//
+// // Find the process and its architecture. Make sure it matches the architecture
+// // of the current Target, and if not adjust it.
+// Error error;
+//
+// if (!wait_for_launch)
+// {
+// ProcessInstanceInfoList process_infos;
+// PlatformSP platform_sp (m_target.GetPlatform ());
+// assert (platform_sp.get());
+//
+// if (platform_sp)
+// {
+// ProcessInstanceInfoMatch match_info;
+// match_info.GetProcessInfo().SetName(process_name);
+// match_info.SetNameMatchType (eNameMatchEquals);
+// platform_sp->FindProcesses (match_info, process_infos);
+// if (process_infos.GetSize() > 1)
+// {
+// error.SetErrorStringWithFormat ("more than one process named %s", process_name);
+// }
+// else if (process_infos.GetSize() == 0)
+// {
+// error.SetErrorStringWithFormat ("could not find a process named %s", process_name);
+// }
+// }
+// else
+// {
+// error.SetErrorString ("invalid platform");
+// }
+// }
+//
+// if (error.Success())
+// {
+// m_dyld_ap.reset();
+// m_os_ap.reset();
+//
+// error = WillAttachToProcessWithName(process_name, wait_for_launch);
+// if (error.Success())
+// {
+// SetPublicState (eStateAttaching);
+// error = DoAttachToProcessWithName (process_name, wait_for_launch);
+// if (error.Fail())
+// {
+// if (GetID() != LLDB_INVALID_PROCESS_ID)
+// {
+// SetID (LLDB_INVALID_PROCESS_ID);
+// const char *error_string = error.AsCString();
+// if (error_string == NULL)
+// error_string = "attach failed";
+//
+// SetExitStatus(-1, error_string);
+// }
+// }
+// else
+// {
+// SetNextEventAction(new Process::AttachCompletionHandler(this, 0));
+// StartPrivateStateThread();
+// }
+// }
+// }
+// return error;
+//}
+
void
Process::CompleteAttach ()
{
OpenPOWER on IntegriCloud