diff --git a/lldb/source/Host/posix/Mutex.cpp b/lldb/source/Host/posix/Mutex.cpp index 3f1c83066994..e038102e98ca 100644 --- a/lldb/source/Host/posix/Mutex.cpp +++ b/lldb/source/Host/posix/Mutex.cpp @@ -78,8 +78,7 @@ Mutex::Locker::Locker (pthread_mutex_t *mutex_ptr) : //---------------------------------------------------------------------- Mutex::Locker::~Locker () { - if (m_mutex_ptr) - Mutex::Unlock (m_mutex_ptr); + Reset(); } //---------------------------------------------------------------------- @@ -89,6 +88,10 @@ Mutex::Locker::~Locker () void Mutex::Locker::Reset (pthread_mutex_t *mutex_ptr) { + // We already have this mutex locked or both are NULL... + if (m_mutex_ptr == mutex_ptr) + return; + if (m_mutex_ptr) Mutex::Unlock (m_mutex_ptr); @@ -100,9 +103,12 @@ Mutex::Locker::Reset (pthread_mutex_t *mutex_ptr) bool Mutex::Locker::TryLock (pthread_mutex_t *mutex_ptr) { - if (m_mutex_ptr) - Mutex::Unlock (m_mutex_ptr); - m_mutex_ptr = NULL; + // We already have this mutex locked! + if (m_mutex_ptr == mutex_ptr) + return true; + + Reset (); + if (mutex_ptr) { if (Mutex::TryLock (mutex_ptr) == 0) diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp index 062bd25d182c..0f7787bf2ce7 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp @@ -124,7 +124,7 @@ GDBRemoteCommunication::SendPacketAndWaitForResponse timeout_time = TimeValue::Now(); timeout_time.OffsetWithSeconds (timeout_seconds); - if (locker.TryLock (m_sequence_mutex.GetMutex())) + if (GetSequenceMutex (locker)) { if (SendPacketNoLock (payload, strlen(payload))) return WaitForPacketNoLock (response, &timeout_time); @@ -139,7 +139,7 @@ GDBRemoteCommunication::SendPacketAndWaitForResponse m_async_packet_predicate.SetValue (true, eBroadcastNever); bool timed_out = false; - if (SendInterrupt(1, &timed_out)) + if (SendInterrupt(locker, 1, &timed_out)) { if (m_async_packet_predicate.WaitForValueEqualTo (false, &timeout_time, &timed_out)) { @@ -396,14 +396,25 @@ GDBRemoteCommunication::SendAsyncSignal (int signo) { m_async_signal = signo; bool timed_out = false; - if (SendInterrupt(1, &timed_out)) + Mutex::Locker locker; + if (SendInterrupt (locker, 1, &timed_out)) return true; m_async_signal = -1; return false; } +// This function takes a mutex locker as a parameter in case the GetSequenceMutex +// actually succeeds. If it doesn't succeed in acquiring the sequence mutex +// (the expected result), then it will send the halt packet. If it does succeed +// then the caller that requested the interrupt will want to keep the sequence +// locked down so that no one else can send packets while the caller has control. +// This function usually gets called when we are running and need to stop the +// target. It can also be used when we are running and and we need to do something +// else (like read/write memory), so we need to interrupt the running process +// (gdb remote protocol requires this), and do what we need to do, then resume. + bool -GDBRemoteCommunication::SendInterrupt (uint32_t seconds_to_wait_for_stop, bool *timed_out) +GDBRemoteCommunication::SendInterrupt (Mutex::Locker& locker, uint32_t seconds_to_wait_for_stop, bool *timed_out) { if (timed_out) *timed_out = false; @@ -411,7 +422,7 @@ GDBRemoteCommunication::SendInterrupt (uint32_t seconds_to_wait_for_stop, bool * if (IsConnected() && IsRunning()) { // Only send an interrupt if our debugserver is running... - if (m_sequence_mutex.TryLock() != 0) + if (GetSequenceMutex (locker) == false) { // Someone has the mutex locked waiting for a response or for the // inferior to stop, so send the interrupt on the down low... diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h index 9351c6a77903..e5560720f4c7 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h @@ -99,7 +99,9 @@ public: SendAsyncSignal (int signo); bool - SendInterrupt (uint32_t seconds_to_wait_for_stop, bool *timed_out = NULL); + SendInterrupt (lldb_private::Mutex::Locker &locker, + uint32_t seconds_to_wait_for_stop, + bool *timed_out = NULL); bool GetSequenceMutex(lldb_private::Mutex::Locker& locker); diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index aa3cf6b0308c..815ceceb0362 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -1117,7 +1117,8 @@ ProcessGDBRemote::DoHalt () if (m_gdb_comm.IsRunning()) { bool timed_out = false; - if (!m_gdb_comm.SendInterrupt (2, &timed_out)) + Mutex::Locker locker; + if (!m_gdb_comm.SendInterrupt (locker, 2, &timed_out)) { if (timed_out) error.SetErrorString("timed out sending interrupt packet"); @@ -1150,7 +1151,8 @@ ProcessGDBRemote::DoDestroy () log->Printf ("ProcessGDBRemote::DoDestroy()"); // Interrupt if our inferior is running... - m_gdb_comm.SendInterrupt (1); + Mutex::Locker locker; + m_gdb_comm.SendInterrupt (locker, 1); DisableAllBreakpointSites (); SetExitStatus(-1, "process killed"); diff --git a/lldb/tools/debugserver/debugserver.xcodeproj/project.pbxproj b/lldb/tools/debugserver/debugserver.xcodeproj/project.pbxproj index 03653d36b9ff..4663ccc5529b 100644 --- a/lldb/tools/debugserver/debugserver.xcodeproj/project.pbxproj +++ b/lldb/tools/debugserver/debugserver.xcodeproj/project.pbxproj @@ -369,7 +369,14 @@ isa = PBXProject; buildConfigurationList = 1DEB914E08733D8E0010E9CD /* Build configuration list for PBXProject "debugserver" */; compatibilityVersion = "Xcode 3.1"; + developmentRegion = English; hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + ); mainGroup = 08FB7794FE84155DC02AAC07 /* dbgnub */; projectDirPath = ""; projectRoot = "";