[Lldb-commits] [lldb] r180831 - Added an option to "process detach" to keep the process stopped, if the process plugin (or in the
Jim Ingham
jingham at apple.com
Tue Apr 30 16:46:09 PDT 2013
Author: jingham
Date: Tue Apr 30 18:46:08 2013
New Revision: 180831
URL: http://llvm.org/viewvc/llvm-project?rev=180831&view=rev
Log:
Added an option to "process detach" to keep the process stopped, if the process plugin (or in the
case of ProcessGDBRemote the stub we are talking to) know how to do that.
rdar://problem/13680832
Modified:
lldb/trunk/include/lldb/API/SBProcess.h
lldb/trunk/include/lldb/Target/Process.h
lldb/trunk/source/API/SBProcess.cpp
lldb/trunk/source/Commands/CommandObjectProcess.cpp
lldb/trunk/source/Interpreter/CommandObject.cpp
lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h
lldb/trunk/source/Plugins/Process/POSIX/ProcessPOSIX.cpp
lldb/trunk/source/Plugins/Process/POSIX/ProcessPOSIX.h
lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
lldb/trunk/source/Target/Process.cpp
Modified: lldb/trunk/include/lldb/API/SBProcess.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBProcess.h?rev=180831&r1=180830&r2=180831&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBProcess.h (original)
+++ lldb/trunk/include/lldb/API/SBProcess.h Tue Apr 30 18:46:08 2013
@@ -205,6 +205,9 @@ public:
Detach ();
lldb::SBError
+ Detach (bool keep_stopped);
+
+ lldb::SBError
Signal (int signal);
void
Modified: lldb/trunk/include/lldb/Target/Process.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Process.h?rev=180831&r1=180830&r2=180831&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/Process.h (original)
+++ lldb/trunk/include/lldb/Target/Process.h Tue Apr 30 18:46:08 2013
@@ -91,6 +91,12 @@ public:
void
SetStopOnSharedLibraryEvents (bool stop);
+
+ bool
+ GetDetachKeepsStopped () const;
+
+ void
+ SetDetachKeepsStopped (bool keep_stopped);
};
typedef std::shared_ptr<ProcessProperties> ProcessPropertiesSP;
@@ -1943,11 +1949,14 @@ public:
/// This function is not meant to be overridden by Process
/// subclasses.
///
+ /// @param[in] keep_stopped
+ /// If true, don't resume the process on detach.
+ ///
/// @return
/// Returns an error object.
//------------------------------------------------------------------
Error
- Detach ();
+ Detach (bool keep_stopped);
//------------------------------------------------------------------
/// Kills the process and shuts down all threads that were spawned
@@ -2334,7 +2343,7 @@ public:
/// false otherwise.
//------------------------------------------------------------------
virtual Error
- DoDetach ()
+ DoDetach (bool keep_stopped)
{
Error error;
error.SetErrorStringWithFormat("error: %s does not support detaching from processes", GetShortPluginName());
Modified: lldb/trunk/source/API/SBProcess.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBProcess.cpp?rev=180831&r1=180830&r2=180831&view=diff
==============================================================================
--- lldb/trunk/source/API/SBProcess.cpp (original)
+++ lldb/trunk/source/API/SBProcess.cpp Tue Apr 30 18:46:08 2013
@@ -786,12 +786,20 @@ SBProcess::Kill ()
SBError
SBProcess::Detach ()
{
+ // FIXME: This should come from a process default.
+ bool keep_stopped = false;
+ Detach (keep_stopped);
+}
+
+SBError
+SBProcess::Detach (bool keep_stopped)
+{
SBError sb_error;
ProcessSP process_sp(GetSP());
if (process_sp)
{
Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
- sb_error.SetError (process_sp->Detach());
+ sb_error.SetError (process_sp->Detach(keep_stopped));
}
else
sb_error.SetErrorString ("SBProcess is invalid");
Modified: lldb/trunk/source/Commands/CommandObjectProcess.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectProcess.cpp?rev=180831&r1=180830&r2=180831&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectProcess.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectProcess.cpp Tue Apr 30 18:46:08 2013
@@ -75,7 +75,8 @@ protected:
{
if (process->GetShouldDetach())
{
- Error detach_error (process->Detach());
+ bool keep_stopped = false;
+ Error detach_error (process->Detach(keep_stopped));
if (detach_error.Success())
{
result.SetStatus (eReturnStatusSuccessFinishResult);
@@ -903,6 +904,68 @@ CommandObjectProcessContinue::CommandOpt
class CommandObjectProcessDetach : public CommandObjectParsed
{
public:
+ class CommandOptions : public Options
+ {
+ public:
+
+ CommandOptions (CommandInterpreter &interpreter) :
+ Options (interpreter)
+ {
+ OptionParsingStarting ();
+ }
+
+ ~CommandOptions ()
+ {
+ }
+
+ Error
+ SetOptionValue (uint32_t option_idx, const char *option_arg)
+ {
+ Error error;
+ const int short_option = m_getopt_table[option_idx].val;
+
+ switch (short_option)
+ {
+ case 's':
+ bool tmp_result;
+ bool success;
+ tmp_result = Args::StringToBoolean(option_arg, false, &success);
+ if (!success)
+ error.SetErrorStringWithFormat("invalid boolean option: \"%s\"", option_arg);
+ else
+ {
+ if (tmp_result)
+ m_keep_stopped = eLazyBoolYes;
+ else
+ m_keep_stopped = eLazyBoolNo;
+ }
+ break;
+ default:
+ error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
+ break;
+ }
+ return error;
+ }
+
+ void
+ OptionParsingStarting ()
+ {
+ m_keep_stopped = eLazyBoolCalculate;
+ }
+
+ const OptionDefinition*
+ GetDefinitions ()
+ {
+ return g_option_table;
+ }
+
+ // Options table: Required for subclasses of Options.
+
+ static OptionDefinition g_option_table[];
+
+ // Instance variables to hold the values for command options.
+ LazyBool m_keep_stopped;
+ };
CommandObjectProcessDetach (CommandInterpreter &interpreter) :
CommandObjectParsed (interpreter,
@@ -911,7 +974,8 @@ public:
"process detach",
eFlagRequiresProcess |
eFlagTryTargetAPILock |
- eFlagProcessMustBeLaunched)
+ eFlagProcessMustBeLaunched),
+ m_options(interpreter)
{
}
@@ -919,13 +983,35 @@ public:
{
}
+ Options *
+ GetOptions ()
+ {
+ return &m_options;
+ }
+
+
protected:
bool
DoExecute (Args& command, CommandReturnObject &result)
{
Process *process = m_exe_ctx.GetProcessPtr();
result.AppendMessageWithFormat ("Detaching from process %" PRIu64 "\n", process->GetID());
- Error error (process->Detach());
+ // FIXME: This will be a Command Option:
+ bool keep_stopped;
+ if (m_options.m_keep_stopped == eLazyBoolCalculate)
+ {
+ // Check the process default:
+ if (process->GetDetachKeepsStopped())
+ keep_stopped = true;
+ else
+ keep_stopped = false;
+ }
+ else if (m_options.m_keep_stopped == eLazyBoolYes)
+ keep_stopped = true;
+ else
+ keep_stopped = false;
+
+ Error error (process->Detach(keep_stopped));
if (error.Success())
{
result.SetStatus (eReturnStatusSuccessFinishResult);
@@ -938,6 +1024,15 @@ protected:
}
return result.Succeeded();
}
+
+ CommandOptions m_options;
+};
+
+OptionDefinition
+CommandObjectProcessDetach::CommandOptions::g_option_table[] =
+{
+{ LLDB_OPT_SET_1, false, "keep-stopped", 's', required_argument, NULL, 0, eArgTypeBoolean, "Whether or not the process should be kept stopped on detach (if possible)." },
+{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
};
//-------------------------------------------------------------------------
Modified: lldb/trunk/source/Interpreter/CommandObject.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/CommandObject.cpp?rev=180831&r1=180830&r2=180831&view=diff
==============================================================================
--- lldb/trunk/source/Interpreter/CommandObject.cpp (original)
+++ lldb/trunk/source/Interpreter/CommandObject.cpp Tue Apr 30 18:46:08 2013
@@ -295,7 +295,6 @@ CommandObject::CheckRequirements (Comman
else
{
StateType state = process->GetState();
-
switch (state)
{
case eStateInvalid:
Modified: lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp?rev=180831&r1=180830&r2=180831&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp (original)
+++ lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp Tue Apr 30 18:46:08 2013
@@ -507,12 +507,12 @@ ProcessKDP::DoHalt (bool &caused_stop)
}
Error
-ProcessKDP::DoDetach()
+ProcessKDP::DoDetach(bool keep_stopped)
{
Error error;
Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
if (log)
- log->Printf ("ProcessKDP::DoDetach()");
+ log->Printf ("ProcessKDP::DoDetach(keep_stopped = %i)", keep_stopped);
if (m_comm.IsRunning())
{
@@ -525,7 +525,8 @@ ProcessKDP::DoDetach()
m_thread_list.DiscardThreadPlans();
- if (m_comm.IsConnected())
+ // If we are going to keep the target stopped, then don't send the disconnect message.
+ if (!keep_stopped && m_comm.IsConnected())
{
m_comm.SendRequestDisconnect();
@@ -554,7 +555,8 @@ Error
ProcessKDP::DoDestroy ()
{
// For KDP there really is no difference between destroy and detach
- return DoDetach();
+ bool keep_stopped = false;
+ return DoDetach(keep_stopped);
}
//------------------------------------------------------------------
Modified: lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h?rev=180831&r1=180830&r2=180831&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h (original)
+++ lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h Tue Apr 30 18:46:08 2013
@@ -135,7 +135,7 @@ public:
DoHalt (bool &caused_stop);
virtual lldb_private::Error
- DoDetach ();
+ DoDetach (bool keep_stopped);
virtual lldb_private::Error
DoSignal (int signal);
Modified: lldb/trunk/source/Plugins/Process/POSIX/ProcessPOSIX.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/POSIX/ProcessPOSIX.cpp?rev=180831&r1=180830&r2=180831&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/POSIX/ProcessPOSIX.cpp (original)
+++ lldb/trunk/source/Plugins/Process/POSIX/ProcessPOSIX.cpp Tue Apr 30 18:46:08 2013
@@ -283,9 +283,16 @@ ProcessPOSIX::DoHalt(bool &caused_stop)
}
Error
-ProcessPOSIX::DoDetach()
+ProcessPOSIX::DoDetach(bool keep_stopped)
{
Error error;
+ if (keep_stopped)
+ {
+ // FIXME: If you want to implement keep_stopped on Linux,
+ // this would be the place to do it.
+ error.SetErrorString("Detaching with keep_stopped true is not currently supported on Linux.");
+ return error;
+ }
error = m_monitor->Detach();
if (error.Success())
Modified: lldb/trunk/source/Plugins/Process/POSIX/ProcessPOSIX.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/POSIX/ProcessPOSIX.h?rev=180831&r1=180830&r2=180831&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/POSIX/ProcessPOSIX.h (original)
+++ lldb/trunk/source/Plugins/Process/POSIX/ProcessPOSIX.h Tue Apr 30 18:46:08 2013
@@ -65,7 +65,7 @@ public:
DoHalt(bool &caused_stop);
virtual lldb_private::Error
- DoDetach();
+ DoDetach(bool keep_stopped);
virtual lldb_private::Error
DoSignal(int signal);
Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp?rev=180831&r1=180830&r2=180831&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp Tue Apr 30 18:46:08 2013
@@ -52,6 +52,7 @@ GDBRemoteCommunicationClient::GDBRemoteC
m_supports_alloc_dealloc_memory (eLazyBoolCalculate),
m_supports_memory_region_info (eLazyBoolCalculate),
m_supports_watchpoint_support_info (eLazyBoolCalculate),
+ m_supports_detach_stay_stopped (eLazyBoolCalculate),
m_watchpoints_trigger_after_instruction(eLazyBoolCalculate),
m_attach_or_wait_reply(eLazyBoolCalculate),
m_prepare_for_reg_writing_reply (eLazyBoolCalculate),
@@ -1396,10 +1397,48 @@ GDBRemoteCommunicationClient::Deallocate
return false;
}
-bool
-GDBRemoteCommunicationClient::Detach ()
+Error
+GDBRemoteCommunicationClient::Detach (bool keep_stopped)
{
- return SendPacket ("D", 1) > 0;
+ Error error;
+
+ if (keep_stopped)
+ {
+ if (m_supports_detach_stay_stopped == eLazyBoolCalculate)
+ {
+ char packet[64];
+ const int packet_len = ::snprintf(packet, sizeof(packet), "qSupportsDetachAndStayStopped:");
+ assert (packet_len < sizeof(packet));
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
+ {
+ m_supports_detach_stay_stopped = eLazyBoolYes;
+ }
+ else
+ {
+ m_supports_detach_stay_stopped = eLazyBoolNo;
+ }
+ }
+
+ if (m_supports_detach_stay_stopped == eLazyBoolNo)
+ {
+ error.SetErrorString("Stays stopped not supported by this target.");
+ return error;
+ }
+ else
+ {
+ size_t num_sent = SendPacket ("D1", 2);
+ if (num_sent == 0)
+ error.SetErrorString ("Sending extended disconnect packet failed.");
+ }
+ }
+ else
+ {
+ size_t num_sent = SendPacket ("D", 1);
+ if (num_sent == 0)
+ error.SetErrorString ("Sending disconnect packet failed.");
+ }
+ return error;
}
Error
Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h?rev=180831&r1=180830&r2=180831&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h Tue Apr 30 18:46:08 2013
@@ -199,8 +199,8 @@ public:
bool
DeallocateMemory (lldb::addr_t addr);
- bool
- Detach ();
+ lldb_private::Error
+ Detach (bool keep_stopped);
lldb_private::Error
GetMemoryRegionInfo (lldb::addr_t addr,
@@ -381,6 +381,7 @@ protected:
lldb_private::LazyBool m_supports_alloc_dealloc_memory;
lldb_private::LazyBool m_supports_memory_region_info;
lldb_private::LazyBool m_supports_watchpoint_support_info;
+ lldb_private::LazyBool m_supports_detach_stay_stopped;
lldb_private::LazyBool m_watchpoints_trigger_after_instruction;
lldb_private::LazyBool m_attach_or_wait_reply;
lldb_private::LazyBool m_prepare_for_reg_writing_reply;
Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp?rev=180831&r1=180830&r2=180831&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp Tue Apr 30 18:46:08 2013
@@ -1703,25 +1703,29 @@ ProcessGDBRemote::DoHalt (bool &caused_s
}
Error
-ProcessGDBRemote::DoDetach()
+ProcessGDBRemote::DoDetach(bool keep_stopped)
{
Error error;
Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
if (log)
- log->Printf ("ProcessGDBRemote::DoDetach()");
-
+ log->Printf ("ProcessGDBRemote::DoDetach(keep_stopped: %i)", keep_stopped);
+
DisableAllBreakpointSites ();
m_thread_list.DiscardThreadPlans();
- bool success = m_gdb_comm.Detach ();
+ error = m_gdb_comm.Detach (keep_stopped);
if (log)
{
- if (success)
+ if (error.Success())
log->PutCString ("ProcessGDBRemote::DoDetach() detach packet sent successfully");
else
- log->PutCString ("ProcessGDBRemote::DoDetach() detach packet send failed");
+ log->Printf ("ProcessGDBRemote::DoDetach() detach packet send failed: %s", error.AsCString() ? error.AsCString() : "<unknown error>");
}
+
+ if (!error.Success())
+ return error;
+
// Sleep for one second to let the process get all detached...
StopAsyncThread ();
Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h?rev=180831&r1=180830&r2=180831&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h Tue Apr 30 18:46:08 2013
@@ -141,7 +141,7 @@ public:
DoHalt (bool &caused_stop);
virtual lldb_private::Error
- DoDetach ();
+ DoDetach (bool keep_stopped);
virtual bool
DetachRequiresHalt() { return true; }
Modified: lldb/trunk/source/Target/Process.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Process.cpp?rev=180831&r1=180830&r2=180831&view=diff
==============================================================================
--- lldb/trunk/source/Target/Process.cpp (original)
+++ lldb/trunk/source/Target/Process.cpp Tue Apr 30 18:46:08 2013
@@ -101,6 +101,7 @@ g_properties[] =
{ "unwind-on-error-in-expressions", OptionValue::eTypeBoolean, true, true, NULL, NULL, "If true, errors in expression evaluation will unwind the stack back to the state before the call." },
{ "python-os-plugin-path", OptionValue::eTypeFileSpec, false, true, NULL, NULL, "A path to a python OS plug-in module file that contains a OperatingSystemPlugIn class." },
{ "stop-on-sharedlibrary-events" , OptionValue::eTypeBoolean, true, false, NULL, NULL, "If true, stop when a shared library is loaded or unloaded." },
+ { "detach-keeps-stopped" , OptionValue::eTypeBoolean, true, false, NULL, NULL, "If true, detach will attempt to keep the process stopped." },
{ NULL , OptionValue::eTypeInvalid, false, 0, NULL, NULL, NULL }
};
@@ -110,7 +111,8 @@ enum {
ePropertyIgnoreBreakpointsInExpressions,
ePropertyUnwindOnErrorInExpressions,
ePropertyPythonOSPluginPath,
- ePropertyStopOnSharedLibraryEvents
+ ePropertyStopOnSharedLibraryEvents,
+ ePropertyDetachKeepsStopped
};
ProcessProperties::ProcessProperties (bool is_global) :
@@ -213,6 +215,20 @@ ProcessProperties::SetStopOnSharedLibrar
m_collection_sp->SetPropertyAtIndexAsBoolean(NULL, idx, stop);
}
+bool
+ProcessProperties::GetDetachKeepsStopped () const
+{
+ const uint32_t idx = ePropertyDetachKeepsStopped;
+ return m_collection_sp->GetPropertyAtIndexAsBoolean(NULL, idx, g_properties[idx].default_uint_value != 0);
+}
+
+void
+ProcessProperties::SetDetachKeepsStopped (bool stop)
+{
+ const uint32_t idx = ePropertyDetachKeepsStopped;
+ m_collection_sp->SetPropertyAtIndexAsBoolean(NULL, idx, stop);
+}
+
void
ProcessInstanceInfo::Dump (Stream &s, Platform *platform) const
{
@@ -1096,7 +1112,11 @@ Process::Finalize()
case eStateCrashed:
case eStateSuspended:
if (GetShouldDetach())
- Detach();
+ {
+ // FIXME: This will have to be a process setting:
+ bool keep_stopped = false;
+ Detach(keep_stopped);
+ }
else
Destroy();
break;
@@ -3431,7 +3451,7 @@ Process::HaltForDestroyOrDetach(lldb::Ev
}
Error
-Process::Detach ()
+Process::Detach (bool keep_stopped)
{
EventSP exit_event_sp;
Error error;
@@ -3458,12 +3478,16 @@ Process::Detach ()
}
}
- error = DoDetach();
+ error = DoDetach(keep_stopped);
if (error.Success())
{
DidDetach();
StopPrivateStateThread();
}
+ else
+ {
+ return error;
+ }
}
m_destroy_in_process = false;
More information about the lldb-commits
mailing list