[Lldb-commits] [lldb] r197247 - Centralized the launching of a process into Target::Launch()
Greg Clayton
gclayton at apple.com
Fri Dec 13 09:20:18 PST 2013
Author: gclayton
Date: Fri Dec 13 11:20:18 2013
New Revision: 197247
URL: http://llvm.org/viewvc/llvm-project?rev=197247&view=rev
Log:
Centralized the launching of a process into Target::Launch()
While investigating test suite failures when running the test suite remotely, I noticed we had 3 copies of code that launched a process:
1 - in "process launch" command
2 - SBTarget::Launch() with args
3 - SBTarget::Launch() with SBLaunchInfo
"process launch" was launching through the platform if it was supported (this is needed for remote debugging) and the 2 and 3 were not.
Now all code is in one place.
Modified:
lldb/trunk/include/lldb/Target/Target.h
lldb/trunk/source/API/SBTarget.cpp
lldb/trunk/source/Commands/CommandObjectProcess.cpp
lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
lldb/trunk/source/Target/Target.cpp
Modified: lldb/trunk/include/lldb/Target/Target.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Target.h?rev=197247&r1=197246&r2=197247&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/Target.h (original)
+++ lldb/trunk/include/lldb/Target/Target.h Fri Dec 13 11:20:18 2013
@@ -529,6 +529,10 @@ public:
void
Destroy();
+
+ Error
+ Launch (Listener &listener,
+ ProcessLaunchInfo &launch_info);
//------------------------------------------------------------------
// This part handles the breakpoints.
Modified: lldb/trunk/source/API/SBTarget.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBTarget.cpp?rev=197247&r1=197246&r2=197247&view=diff
==============================================================================
--- lldb/trunk/source/API/SBTarget.cpp (original)
+++ lldb/trunk/source/API/SBTarget.cpp Fri Dec 13 11:20:18 2013
@@ -689,57 +689,26 @@ SBTarget::Launch
return sb_process;
}
}
- else
- {
- if (listener.IsValid())
- process_sp = target_sp->CreateProcess (listener.ref(), NULL, NULL);
- else
- process_sp = target_sp->CreateProcess (target_sp->GetDebugger().GetListener(), NULL, NULL);
- }
- if (process_sp)
- {
- sb_process.SetSP (process_sp);
- if (getenv("LLDB_LAUNCH_FLAG_DISABLE_STDIO"))
- launch_flags |= eLaunchFlagDisableSTDIO;
+ if (getenv("LLDB_LAUNCH_FLAG_DISABLE_STDIO"))
+ launch_flags |= eLaunchFlagDisableSTDIO;
- ProcessLaunchInfo launch_info (stdin_path, stdout_path, stderr_path, working_directory, launch_flags);
-
- Module *exe_module = target_sp->GetExecutableModulePointer();
- if (exe_module)
- launch_info.SetExecutableFile(exe_module->GetPlatformFileSpec(), true);
- if (argv)
- launch_info.GetArguments().AppendArguments (argv);
- if (envp)
- launch_info.GetEnvironmentEntries ().SetArguments (envp);
-
- error.SetError (process_sp->Launch (launch_info));
- if (error.Success())
- {
- // We we are stopping at the entry point, we can return now!
- if (stop_at_entry)
- return sb_process;
-
- // Make sure we are stopped at the entry
- StateType state = process_sp->WaitForProcessToStop (NULL);
- if (state == eStateStopped)
- {
- // resume the process to skip the entry point
- error.SetError (process_sp->Resume());
- if (error.Success())
- {
- // If we are doing synchronous mode, then wait for the
- // process to stop yet again!
- if (target_sp->GetDebugger().GetAsyncExecution () == false)
- process_sp->WaitForProcessToStop (NULL);
- }
- }
- }
- }
+ ProcessLaunchInfo launch_info (stdin_path, stdout_path, stderr_path, working_directory, launch_flags);
+
+ Module *exe_module = target_sp->GetExecutableModulePointer();
+ if (exe_module)
+ launch_info.SetExecutableFile(exe_module->GetPlatformFileSpec(), true);
+ if (argv)
+ launch_info.GetArguments().AppendArguments (argv);
+ if (envp)
+ launch_info.GetEnvironmentEntries ().SetArguments (envp);
+
+ if (listener.IsValid())
+ error.SetError (target_sp->Launch(listener.ref(), launch_info));
else
- {
- error.SetErrorString ("unable to create lldb_private::Process");
- }
+ error.SetError (target_sp->Launch(target_sp->GetDebugger().GetListener(), launch_info));
+
+ sb_process.SetSP(target_sp->GetProcessSP());
}
else
{
@@ -750,7 +719,7 @@ SBTarget::Launch
if (log)
{
log->Printf ("SBTarget(%p)::Launch (...) => SBProcess(%p)",
- target_sp.get(), process_sp.get());
+ target_sp.get(), sb_process.GetSP().get());
}
return sb_process;
@@ -762,7 +731,6 @@ SBTarget::Launch (SBLaunchInfo &sb_launc
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
SBProcess sb_process;
- ProcessSP process_sp;
TargetSP target_sp(GetSP());
if (log)
@@ -774,7 +742,8 @@ SBTarget::Launch (SBLaunchInfo &sb_launc
{
Mutex::Locker api_locker (target_sp->GetAPIMutex());
StateType state = eStateInvalid;
- process_sp = target_sp->GetProcessSP();
+ {
+ ProcessSP process_sp = target_sp->GetProcessSP();
if (process_sp)
{
state = process_sp->GetState();
@@ -788,58 +757,20 @@ SBTarget::Launch (SBLaunchInfo &sb_launc
return sb_process;
}
}
-
- if (state != eStateConnected)
- process_sp = target_sp->CreateProcess (target_sp->GetDebugger().GetListener(), NULL, NULL);
-
- if (process_sp)
- {
- sb_process.SetSP (process_sp);
- lldb_private::ProcessLaunchInfo &launch_info = sb_launch_info.ref();
-
- Module *exe_module = target_sp->GetExecutableModulePointer();
- if (exe_module)
- launch_info.SetExecutableFile(exe_module->GetPlatformFileSpec(), true);
-
- const ArchSpec &arch_spec = target_sp->GetArchitecture();
- if (arch_spec.IsValid())
- launch_info.GetArchitecture () = arch_spec;
-
- error.SetError (process_sp->Launch (launch_info));
- const bool synchronous_execution = target_sp->GetDebugger().GetAsyncExecution () == false;
- if (error.Success())
- {
- if (launch_info.GetFlags().Test(eLaunchFlagStopAtEntry))
- {
- // If we are doing synchronous mode, then wait for the initial
- // stop to happen, else, return and let the caller watch for
- // the stop
- if (synchronous_execution)
- process_sp->WaitForProcessToStop (NULL);
- // We we are stopping at the entry point, we can return now!
- return sb_process;
- }
-
- // Make sure we are stopped at the entry
- StateType state = process_sp->WaitForProcessToStop (NULL);
- if (state == eStateStopped)
- {
- // resume the process to skip the entry point
- error.SetError (process_sp->Resume());
- if (error.Success())
- {
- // If we are doing synchronous mode, then wait for the
- // process to stop yet again!
- if (synchronous_execution)
- process_sp->WaitForProcessToStop (NULL);
- }
- }
- }
- }
- else
- {
- error.SetErrorString ("unable to create lldb_private::Process");
}
+
+ lldb_private::ProcessLaunchInfo &launch_info = sb_launch_info.ref();
+
+ Module *exe_module = target_sp->GetExecutableModulePointer();
+ if (exe_module)
+ launch_info.SetExecutableFile(exe_module->GetPlatformFileSpec(), true);
+
+ const ArchSpec &arch_spec = target_sp->GetArchitecture();
+ if (arch_spec.IsValid())
+ launch_info.GetArchitecture () = arch_spec;
+
+ error.SetError (target_sp->Launch (target_sp->GetDebugger().GetListener(), launch_info));
+ sb_process.SetSP(target_sp->GetProcessSP());
}
else
{
@@ -849,8 +780,8 @@ SBTarget::Launch (SBLaunchInfo &sb_launc
log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API);
if (log)
{
- log->Printf ("SBTarget(%p)::Launch (...) => SBProcess(%p)",
- target_sp.get(), process_sp.get());
+ log->Printf ("SBTarget(%p)::Launch (...) => SBProcess(%p)",
+ target_sp.get(), sb_process.GetSP().get());
}
return sb_process;
Modified: lldb/trunk/source/Commands/CommandObjectProcess.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectProcess.cpp?rev=197247&r1=197246&r2=197247&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectProcess.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectProcess.cpp Fri Dec 13 11:20:18 2013
@@ -49,7 +49,7 @@ public:
virtual ~CommandObjectProcessLaunchOrAttach () {}
protected:
bool
- StopProcessIfNecessary (Process *&process, StateType &state, CommandReturnObject &result)
+ StopProcessIfNecessary (Process *process, StateType &state, CommandReturnObject &result)
{
state = eStateInvalid;
if (process)
@@ -187,12 +187,10 @@ protected:
{
Debugger &debugger = m_interpreter.GetDebugger();
Target *target = debugger.GetSelectedTarget().get();
- Error error;
// If our listener is NULL, users aren't allows to launch
- char filename[PATH_MAX];
- const Module *exe_module = target->GetExecutableModulePointer();
+ ModuleSP exe_module_sp = target->GetExecutableModule();
- if (exe_module == NULL)
+ if (exe_module_sp == NULL)
{
result.AppendError ("no file in target, create a debug target using the 'target create' command");
result.SetStatus (eReturnStatusFailed);
@@ -200,23 +198,31 @@ protected:
}
StateType state = eStateInvalid;
- Process *process = m_exe_ctx.GetProcessPtr();
- if (!StopProcessIfNecessary(process, state, result))
+ if (!StopProcessIfNecessary(m_exe_ctx.GetProcessPtr(), state, result))
return false;
const char *target_settings_argv0 = target->GetArg0();
- exe_module->GetFileSpec().GetPath (filename, sizeof(filename));
+ if (target->GetDisableASLR())
+ m_options.launch_info.GetFlags().Set (eLaunchFlagDisableASLR);
+
+ if (target->GetDisableSTDIO())
+ m_options.launch_info.GetFlags().Set (eLaunchFlagDisableSTDIO);
+ Args environment;
+ target->GetEnvironmentAsArgs (environment);
+ if (environment.GetArgumentCount() > 0)
+ m_options.launch_info.GetEnvironmentEntries ().AppendArguments (environment);
+
if (target_settings_argv0)
{
m_options.launch_info.GetArguments().AppendArgument (target_settings_argv0);
- m_options.launch_info.SetExecutableFile(exe_module->GetPlatformFileSpec(), false);
+ m_options.launch_info.SetExecutableFile(exe_module_sp->GetPlatformFileSpec(), false);
}
else
{
- m_options.launch_info.SetExecutableFile(exe_module->GetPlatformFileSpec(), true);
+ m_options.launch_info.SetExecutableFile(exe_module_sp->GetPlatformFileSpec(), true);
}
if (launch_args.GetArgumentCount() == 0)
@@ -228,122 +234,33 @@ protected:
else
{
m_options.launch_info.GetArguments().AppendArguments (launch_args);
-
// Save the arguments for subsequent runs in the current target.
target->SetRunArguments (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);
-
- // Get the value of synchronous execution here. If you wait till after you have started to
- // run, then you could have hit a breakpoint, whose command might switch the value, and
- // then you'll pick up that incorrect value.
- bool synchronous_execution = m_interpreter.GetSynchronous ();
-
- PlatformSP platform_sp (target->GetPlatform());
-
- // Finalize the file actions, and if none were given, default to opening
- // up a pseudo terminal
- const bool default_to_use_pty = platform_sp ? platform_sp->IsHost() : false;
- m_options.launch_info.FinalizeFileActions (target, default_to_use_pty);
-
- if (state == eStateConnected)
- {
- if (m_options.launch_info.GetFlags().Test (eLaunchFlagLaunchInTTY))
- {
- result.AppendWarning("can't launch in tty when launching through a remote connection");
- m_options.launch_info.GetFlags().Clear (eLaunchFlagLaunchInTTY);
- }
- }
-
- if (!m_options.launch_info.GetArchitecture().IsValid())
- m_options.launch_info.GetArchitecture() = target->GetArchitecture();
+ Error error = target->Launch(debugger.GetListener(), m_options.launch_info);
- if (platform_sp && platform_sp->CanDebugProcess ())
- {
- process = target->GetPlatform()->DebugProcess (m_options.launch_info,
- debugger,
- target,
- debugger.GetListener(),
- error).get();
- }
- else
- {
- const char *plugin_name = m_options.launch_info.GetProcessPluginName();
- process = target->CreateProcess (debugger.GetListener(), plugin_name, NULL).get();
- if (process)
- error = process->Launch (m_options.launch_info);
- }
-
- if (process == NULL)
- {
- result.SetError (error, "failed to launch or debug process");
- return false;
- }
-
-
if (error.Success())
{
- const char *archname = exe_module->GetArchitecture().GetArchitectureName();
-
- result.AppendMessageWithFormat ("Process %" PRIu64 " launched: '%s' (%s)\n", process->GetID(), filename, archname);
- result.SetDidChangeProcessState (true);
- if (m_options.launch_info.GetFlags().Test(eLaunchFlagStopAtEntry) == false)
+ const char *archname = exe_module_sp->GetArchitecture().GetArchitectureName();
+ ProcessSP process_sp (target->GetProcessSP());
+ if (process_sp)
{
- result.SetStatus (eReturnStatusSuccessContinuingNoResult);
- StateType state = process->WaitForProcessToStop (NULL, NULL, false);
-
- if (state == eStateStopped)
- {
- error = process->Resume();
- if (error.Success())
- {
- if (synchronous_execution)
- {
- state = process->WaitForProcessToStop (NULL);
- const bool must_be_alive = true;
- if (!StateIsStoppedState(state, must_be_alive))
- {
- result.AppendErrorWithFormat ("process isn't stopped: %s", StateAsCString(state));
- }
- result.SetDidChangeProcessState (true);
- result.SetStatus (eReturnStatusSuccessFinishResult);
- }
- else
- {
- result.SetStatus (eReturnStatusSuccessContinuingNoResult);
- }
- }
- else
- {
- 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.SetStatus (eReturnStatusFailed);
- }
+ 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);
+ }
+ else
+ {
+ result.AppendError("no error returned from Target::Launch, and target has no process");
+ result.SetStatus (eReturnStatusFailed);
}
}
else
{
- result.AppendErrorWithFormat ("process launch failed: %s", error.AsCString());
+ result.AppendError(error.AsCString());
result.SetStatus (eReturnStatusFailed);
}
-
return result.Succeeded();
}
Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h?rev=197247&r1=197246&r2=197247&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h Fri Dec 13 11:20:18 2013
@@ -254,7 +254,7 @@ protected:
// Classes that inherit from GDBRemoteCommunication can see and modify these
//------------------------------------------------------------------
uint32_t m_packet_timeout;
-#ifdef LLDB_CONFIGURATION_DEBUG
+#ifdef ENABLE_MUTEX_ERROR_CHECKING
lldb_private::TrackingMutex m_sequence_mutex;
#else
lldb_private::Mutex m_sequence_mutex; // Restrict access to sending/receiving packets to a single thread at a time
Modified: lldb/trunk/source/Target/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Target.cpp?rev=197247&r1=197246&r2=197247&view=diff
==============================================================================
--- lldb/trunk/source/Target/Target.cpp (original)
+++ lldb/trunk/source/Target/Target.cpp Fri Dec 13 11:20:18 2013
@@ -28,6 +28,7 @@
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/Section.h"
#include "lldb/Core/SourceManager.h"
+#include "lldb/Core/State.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Core/Timer.h"
#include "lldb/Core/ValueObject.h"
@@ -2317,6 +2318,114 @@ Target::ClearAllLoadedSections ()
m_section_load_history.Clear();
}
+
+Error
+Target::Launch (Listener &listener, ProcessLaunchInfo &launch_info)
+{
+ Error error;
+ Error error2;
+
+ StateType state = eStateInvalid;
+
+ launch_info.GetFlags().Set (eLaunchFlagDebug);
+
+ // Get the value of synchronous execution here. If you wait till after you have started to
+ // run, then you could have hit a breakpoint, whose command might switch the value, and
+ // then you'll pick up that incorrect value.
+ Debugger &debugger = GetDebugger();
+ const bool synchronous_execution = debugger.GetCommandInterpreter().GetSynchronous ();
+
+ PlatformSP platform_sp (GetPlatform());
+
+ // Finalize the file actions, and if none were given, default to opening
+ // up a pseudo terminal
+ const bool default_to_use_pty = platform_sp ? platform_sp->IsHost() : false;
+ launch_info.FinalizeFileActions (this, default_to_use_pty);
+
+ if (state == eStateConnected)
+ {
+ if (launch_info.GetFlags().Test (eLaunchFlagLaunchInTTY))
+ {
+ error.SetErrorString("can't launch in tty when launching through a remote connection");
+ return error;
+ }
+ }
+
+ if (!launch_info.GetArchitecture().IsValid())
+ launch_info.GetArchitecture() = GetArchitecture();
+
+ if (state != eStateConnected && platform_sp && platform_sp->CanDebugProcess ())
+ {
+ m_process_sp = GetPlatform()->DebugProcess (launch_info,
+ debugger,
+ this,
+ listener,
+ error);
+ }
+ else
+ {
+ if (state == eStateConnected)
+ {
+ assert(m_process_sp);
+ }
+ else
+ {
+ const char *plugin_name = launch_info.GetProcessPluginName();
+ CreateProcess (listener, plugin_name, NULL);
+ }
+
+ if (m_process_sp)
+ error = m_process_sp->Launch (launch_info);
+ }
+
+ if (!m_process_sp)
+ {
+ if (error.Success())
+ error.SetErrorString("failed to launch or debug process");
+ return error;
+ }
+
+ if (error.Success())
+ {
+ if (launch_info.GetFlags().Test(eLaunchFlagStopAtEntry) == false)
+ {
+ StateType state = m_process_sp->WaitForProcessToStop (NULL, NULL, false);
+
+ if (state == eStateStopped)
+ {
+ error = m_process_sp->Resume();
+ if (error.Success())
+ {
+ if (synchronous_execution)
+ {
+ state = m_process_sp->WaitForProcessToStop (NULL);
+ const bool must_be_alive = false; // eStateExited is ok, so this must be false
+ if (!StateIsStoppedState(state, must_be_alive))
+ {
+ error2.SetErrorStringWithFormat("process isn't stopped: %s", StateAsCString(state));
+ return error2;
+ }
+ }
+ }
+ else
+ {
+ error2.SetErrorStringWithFormat("process resume at entry point failed: %s", error.AsCString());
+ return error2;
+ }
+ }
+ else
+ {
+ error.SetErrorStringWithFormat ("initial process state wasn't stopped: %s", StateAsCString(state));
+ }
+ }
+ }
+ else
+ {
+ error2.SetErrorStringWithFormat ("process launch failed: %s", error.AsCString());
+ return error2;
+ }
+ return error;
+}
//--------------------------------------------------------------
// Target::StopHook
//--------------------------------------------------------------
More information about the lldb-commits
mailing list