[Lldb-commits] [lldb] r167197 - in /lldb/trunk/source/Plugins/Process/gdb-remote: ProcessGDBRemote.cpp ProcessGDBRemote.h
Jim Ingham
jingham at apple.com
Wed Oct 31 18:15:33 PDT 2012
Author: jingham
Date: Wed Oct 31 20:15:33 2012
New Revision: 167197
URL: http://llvm.org/viewvc/llvm-project?rev=167197&view=rev
Log:
There seems to be some odd corner case where we shut down the ProcessGDBRemote, but we haven't managed to shut down the async thread. That causes the ProcessGDBRemote::AsyncThread to crash when it wakes up. So I changed StartAsyncThread and StopAsyncThread to be callable multiple times (only the first one does anything) so that we can just shut it down unequivocally in the ProcessGDBRemote destructor.
<rdar://problem/12602981>
Modified:
lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
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=167197&r1=167196&r2=167197&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp Wed Oct 31 20:15:33 2012
@@ -188,6 +188,8 @@
m_register_info (),
m_async_broadcaster (NULL, "lldb.process.gdb-remote.async-broadcaster"),
m_async_thread (LLDB_INVALID_HOST_THREAD),
+ m_async_thread_state(eAsyncThreadNotStarted),
+ m_async_thread_state_mutex(Mutex::eMutexTypeRecursive),
m_thread_ids (),
m_continue_c_tids (),
m_continue_C_tids (),
@@ -220,6 +222,12 @@
// destruct this class, then Process::~Process() might have problems
// trying to fully destroy the broadcaster.
Finalize();
+
+ // The general Finalize is going to try to destroy the process and that SHOULD
+ // shut down the async thread. However, if we don't kill it it will get stranded and
+ // its connection will go away so when it wakes up it will crash. So kill it for sure here.
+ StopAsyncThread();
+ KillDebugserverProcess();
}
//----------------------------------------------------------------------
@@ -2713,11 +2721,32 @@
if (log)
log->Printf ("ProcessGDBRemote::%s ()", __FUNCTION__);
-
- // Create a thread that watches our internal state and controls which
- // events make it to clients (into the DCProcess event queue).
- m_async_thread = Host::ThreadCreate ("<lldb.process.gdb-remote.async>", ProcessGDBRemote::AsyncThread, this, NULL);
- return IS_VALID_LLDB_HOST_THREAD(m_async_thread);
+
+ Mutex::Locker start_locker(m_async_thread_state_mutex);
+ if (m_async_thread_state == eAsyncThreadNotStarted)
+ {
+ // Create a thread that watches our internal state and controls which
+ // events make it to clients (into the DCProcess event queue).
+ m_async_thread = Host::ThreadCreate ("<lldb.process.gdb-remote.async>", ProcessGDBRemote::AsyncThread, this, NULL);
+ if (IS_VALID_LLDB_HOST_THREAD(m_async_thread))
+ {
+ m_async_thread_state = eAsyncThreadRunning;
+ return true;
+ }
+ else
+ return false;
+ }
+ else
+ {
+ // Somebody tried to start the async thread while it was either being started or stopped. If the former, and
+ // it started up successfully, then say all's well. Otherwise it is an error, since we aren't going to restart it.
+ if (log)
+ log->Printf ("ProcessGDBRemote::%s () - Called when Async thread was in state: %d.", __FUNCTION__, m_async_thread_state);
+ if (m_async_thread_state == eAsyncThreadRunning)
+ return true;
+ else
+ return false;
+ }
}
void
@@ -2728,15 +2757,25 @@
if (log)
log->Printf ("ProcessGDBRemote::%s ()", __FUNCTION__);
- m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncThreadShouldExit);
-
- // This will shut down the async thread.
- m_gdb_comm.Disconnect(); // Disconnect from the debug server.
+ Mutex::Locker start_locker(m_async_thread_state_mutex);
+ if (m_async_thread_state == eAsyncThreadRunning)
+ {
+ m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncThreadShouldExit);
+
+ // This will shut down the async thread.
+ m_gdb_comm.Disconnect(); // Disconnect from the debug server.
- // Stop the stdio thread
- if (IS_VALID_LLDB_HOST_THREAD(m_async_thread))
+ // Stop the stdio thread
+ if (IS_VALID_LLDB_HOST_THREAD(m_async_thread))
+ {
+ Host::ThreadJoin (m_async_thread, NULL, NULL);
+ }
+ m_async_thread_state = eAsyncThreadDone;
+ }
+ else
{
- Host::ThreadJoin (m_async_thread, NULL, NULL);
+ if (log)
+ log->Printf ("ProcessGDBRemote::%s () - Called when Async thread was in state: %d.", __FUNCTION__, m_async_thread_state);
}
}
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=167197&r1=167196&r2=167197&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h Wed Oct 31 20:15:33 2012
@@ -307,6 +307,13 @@
eBroadcastBitAsyncThreadDidExit = (1 << 2)
};
+ typedef enum AsyncThreadState
+ {
+ eAsyncThreadNotStarted,
+ eAsyncThreadRunning,
+ eAsyncThreadDone
+ } AsyncThreadState;
+
lldb_private::Flags m_flags; // Process specific flags (see eFlags enums)
GDBRemoteCommunicationClient m_gdb_comm;
lldb::pid_t m_debugserver_pid;
@@ -315,6 +322,8 @@
GDBRemoteDynamicRegisterInfo m_register_info;
lldb_private::Broadcaster m_async_broadcaster;
lldb::thread_t m_async_thread;
+ AsyncThreadState m_async_thread_state;
+ lldb_private::Mutex m_async_thread_state_mutex;
typedef std::vector<lldb::tid_t> tid_collection;
typedef std::vector< std::pair<lldb::tid_t,int> > tid_sig_collection;
typedef std::map<lldb::addr_t, lldb::addr_t> MMapMap;
More information about the lldb-commits
mailing list