[Lldb-commits] [lldb] r159697 - in /lldb/trunk: include/lldb/Target/Thread.h source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp source/Plugins/Process/gdb-remote/ProcessGDBRemote.h source/Target/Process.cpp
Jim Ingham
jingham at apple.com
Tue Jul 3 17:35:43 PDT 2012
Author: jingham
Date: Tue Jul 3 19:35:43 2012
New Revision: 159697
URL: http://llvm.org/viewvc/llvm-project?rev=159697&view=rev
Log:
Work around some problems destroying a process with older debugservers.
rdar://problem/11359989
Modified:
lldb/trunk/include/lldb/Target/Thread.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/Target/Thread.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Thread.h?rev=159697&r1=159696&r2=159697&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/Thread.h (original)
+++ lldb/trunk/include/lldb/Target/Thread.h Tue Jul 3 19:35:43 2012
@@ -775,6 +775,13 @@
{
return m_destroy_called;
}
+
+ // When you implement this method, make sure you don't overwrite the m_actual_stop_info if it claims to be
+ // valid. The stop info may be a "checkpointed and restored" stop info, so if it is still around it is right
+ // even if you have not calculated this yourself, or if it disagrees with what you might have calculated.
+ virtual lldb::StopInfoSP
+ GetPrivateStopReason () = 0;
+
protected:
friend class ThreadPlan;
@@ -796,12 +803,6 @@
ThreadPlan *GetPreviousPlan (ThreadPlan *plan);
- // When you implement this method, make sure you don't overwrite the m_actual_stop_info if it claims to be
- // valid. The stop info may be a "checkpointed and restored" stop info, so if it is still around it is right
- // even if you have not calculated this yourself, or if it disagrees with what you might have calculated.
- virtual lldb::StopInfoSP
- GetPrivateStopReason () = 0;
-
typedef std::vector<lldb::ThreadPlanSP> plan_stack;
void
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=159697&r1=159696&r2=159697&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp Tue Jul 3 19:35:43 2012
@@ -47,6 +47,7 @@
// Project includes
#include "lldb/Host/Host.h"
#include "Plugins/Process/Utility/InferiorCallPOSIX.h"
+#include "Plugins/Platform/MacOSX/PlatformRemoteiOS.h"
#include "Utility/StringExtractorGDBRemote.h"
#include "GDBRemoteRegisterContext.h"
#include "ProcessGDBRemote.h"
@@ -175,7 +176,8 @@
m_max_memory_size (512),
m_addr_to_mmap_size (),
m_thread_create_bp_sp (),
- m_waiting_for_attach (false)
+ m_waiting_for_attach (false),
+ m_destroy_tried_resuming (false)
{
m_async_broadcaster.SetEventName (eBroadcastBitAsyncThreadShouldExit, "async thread should exit");
m_async_broadcaster.SetEventName (eBroadcastBitAsyncContinue, "async thread continue");
@@ -1689,6 +1691,7 @@
return error;
}
+
Error
ProcessGDBRemote::DoDestroy ()
{
@@ -1697,6 +1700,110 @@
if (log)
log->Printf ("ProcessGDBRemote::DoDestroy()");
+ // There is a bug in older iOS debugservers where they don't shut down the process
+ // they are debugging properly. If the process is sitting at a breakpoint or an exception,
+ // this can cause problems with restarting. So we check to see if any of our threads are stopped
+ // at a breakpoint, and if so we remove all the breakpoints, resume the process, and THEN
+ // destroy it again.
+ //
+ // Note, we don't have a good way to test the version of debugserver, but I happen to know that
+ // the set of all the iOS debugservers which don't support GetThreadSuffixSupported() and that of
+ // the debugservers with this bug are equal. There really should be a better way to test this!
+ //
+ // We also use m_destroy_tried_resuming to make sure we only do this once, if we resume and then halt and
+ // get called here to destroy again and we're still at a breakpoint or exception, then we should
+ // just do the straight-forward kill.
+ //
+ // And of course, if we weren't able to stop the process by the time we get here, it isn't
+ // necessary (or helpful) to do any of this.
+
+ if (!m_gdb_comm.GetThreadSuffixSupported() && m_public_state.GetValue() != eStateRunning)
+ {
+ PlatformSP platform_sp = GetTarget().GetPlatform();
+
+ // FIXME: These should be ConstStrings so we aren't doing strcmp'ing.
+ if (platform_sp
+ && platform_sp->GetName()
+ && strcmp (platform_sp->GetName(), PlatformRemoteiOS::GetShortPluginNameStatic()) == 0)
+ {
+ if (m_destroy_tried_resuming)
+ {
+ if (log)
+ log->PutCString ("ProcessGDBRemote::DoDestroy()Tried resuming to destroy once already, not doing it again.");
+ }
+ else
+ {
+ // At present, the plans are discarded and the breakpoints disabled Process::Destroy,
+ // but we really need it to happen here and it doesn't matter if we do it twice.
+ m_thread_list.DiscardThreadPlans();
+ DisableAllBreakpointSites();
+
+ bool stop_looks_like_crash = false;
+ ThreadList &threads = GetThreadList();
+
+ {
+ Mutex::Locker(threads.GetMutex());
+
+ size_t num_threads = threads.GetSize();
+ for (size_t i = 0; i < num_threads; i++)
+ {
+ ThreadSP thread_sp = threads.GetThreadAtIndex(i);
+ StopInfoSP stop_info_sp = thread_sp->GetPrivateStopReason();
+ StopReason reason = eStopReasonInvalid;
+ if (stop_info_sp)
+ reason = stop_info_sp->GetStopReason();
+ if (reason == eStopReasonBreakpoint
+ || reason == eStopReasonException)
+ {
+ if (log)
+ log->Printf ("ProcessGDBRemote::DoDestroy() - thread: %lld stopped with reason: %s.",
+ thread_sp->GetID(),
+ stop_info_sp->GetDescription());
+ stop_looks_like_crash = true;
+ break;
+ }
+ }
+ }
+
+ if (stop_looks_like_crash)
+ {
+ if (log)
+ log->PutCString ("ProcessGDBRemote::DoDestroy() - Stopped at a breakpoint, continue and then kill.");
+ m_destroy_tried_resuming = true;
+
+ // If we are going to run again before killing, it would be good to suspend all the threads
+ // before resuming so they won't get into more trouble. Sadly, for the threads stopped with
+ // the breakpoint or exception, the exception doesn't get cleared if it is suspended, so we do
+ // have to run the risk of letting those threads proceed a bit.
+
+ {
+ Mutex::Locker(threads.GetMutex());
+
+ size_t num_threads = threads.GetSize();
+ for (size_t i = 0; i < num_threads; i++)
+ {
+ ThreadSP thread_sp = threads.GetThreadAtIndex(i);
+ StopInfoSP stop_info_sp = thread_sp->GetPrivateStopReason();
+ StopReason reason = eStopReasonInvalid;
+ if (stop_info_sp)
+ reason = stop_info_sp->GetStopReason();
+ if (reason != eStopReasonBreakpoint
+ && reason != eStopReasonException)
+ {
+ if (log)
+ log->Printf ("ProcessGDBRemote::DoDestroy() - Suspending thread: %lld before running.",
+ thread_sp->GetID());
+ thread_sp->SetResumeState(eStateSuspended);
+ }
+ }
+ }
+ Resume ();
+ return Destroy();
+ }
+ }
+ }
+ }
+
// Interrupt if our inferior is running...
int exit_status = SIGABRT;
std::string exit_string;
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=159697&r1=159696&r2=159697&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h Tue Jul 3 19:35:43 2012
@@ -321,6 +321,7 @@
MMapMap m_addr_to_mmap_size;
lldb::BreakpointSP m_thread_create_bp_sp;
bool m_waiting_for_attach;
+ bool m_destroy_tried_resuming;
bool
StartAsyncThread ();
Modified: lldb/trunk/source/Target/Process.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Process.cpp?rev=159697&r1=159696&r2=159697&view=diff
==============================================================================
--- lldb/trunk/source/Target/Process.cpp (original)
+++ lldb/trunk/source/Target/Process.cpp Tue Jul 3 19:35:43 2012
@@ -1621,6 +1621,11 @@
Process::DisableAllBreakpointSites ()
{
m_breakpoint_site_list.SetEnabledForAll (false);
+ size_t num_sites = m_breakpoint_site_list.GetSize();
+ for (size_t i = 0; i < num_sites; i++)
+ {
+ DisableBreakpoint (m_breakpoint_site_list.GetByIndex(i).get());
+ }
}
Error
More information about the lldb-commits
mailing list