summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Clayton <gclayton@apple.com>2010-12-03 06:02:24 +0000
committerGreg Clayton <gclayton@apple.com>2010-12-03 06:02:24 +0000
commite5219660542e7126c7de8f2bd945f05d238760a4 (patch)
treeecc0d3c75273eeba285fbcbbefde043e1eea6325
parente0c4560b50b1b89649a8b06c1b138bf1d3bb8c99 (diff)
downloadbcm5719-llvm-e5219660542e7126c7de8f2bd945f05d238760a4.tar.gz
bcm5719-llvm-e5219660542e7126c7de8f2bd945f05d238760a4.zip
Fixed a race condition that could cause ProcessGDBRemote::DoResume() to return
an error saying the resume timed out. Previously the thread that was trying to resume the process would eventually call ProcessGDBRemote::DoResume() which would broadcast an event over to the async GDB remote thread which would sent the continue packet to the remote gdb server. Right after this was sent, it would set a predicate boolean value (protected by a mutex and condition) and then the thread that issued the ProcessGDBRemote::DoResume() would then wait for that condition variable to be set. If the async gdb thread was too quick though, the predicate boolean value could have been set to true and back to false by the time the thread that issued the ProcessGDBRemote::DoResume() checks the boolean value. So we can't use the predicate value as a handshake. I have changed the code over to using a Event by having the GDB remote communication object post an event: GDBRemoteCommunication::eBroadcastBitRunPacketSent This allows reliable handshaking between the two threads and avoids the erroneous ProcessGDBRemote::DoResume() errors. Added a host backtrace service to allow in process backtraces when trying to track down tricky issues. I need to see if LLVM has any backtracing abilities abstracted in it already, and if so, use that, but I needed something ASAP for the current issue I was working on. The static function is: void Host::Backtrace (Stream &strm, uint32_t max_frames); And it will backtrace at most "max_frames" frames for the current thread and can be used with any of the Stream subclasses for logging. llvm-svn: 120793
-rw-r--r--lldb/include/lldb/Host/Host.h3
-rw-r--r--lldb/lldb.xcodeproj/project.pbxproj1
-rw-r--r--lldb/source/Host/common/Host.cpp7
-rw-r--r--lldb/source/Host/macosx/Host.mm33
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp19
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h7
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp20
-rw-r--r--lldb/tools/debugserver/debugserver.xcodeproj/project.pbxproj1
-rw-r--r--lldb/tools/debugserver/source/DNBLog.cpp45
9 files changed, 107 insertions, 29 deletions
diff --git a/lldb/include/lldb/Host/Host.h b/lldb/include/lldb/Host/Host.h
index 34fbf67dc3a..4f6469591d9 100644
--- a/lldb/include/lldb/Host/Host.h
+++ b/lldb/include/lldb/Host/Host.h
@@ -315,7 +315,6 @@ public:
static void
SetCrashDescription (const char *description);
-
static uint32_t
ListProcessesMatchingName (const char *name, StringList &matches, std::vector<lldb::pid_t> &pids);
@@ -339,6 +338,8 @@ public:
static bool
OpenFileInExternalEditor (const FileSpec &file_spec, uint32_t line_no);
+ static void
+ Backtrace (Stream &strm, uint32_t max_frames);
};
} // namespace lldb_private
diff --git a/lldb/lldb.xcodeproj/project.pbxproj b/lldb/lldb.xcodeproj/project.pbxproj
index a4ecb0458db..b4a3afe138f 100644
--- a/lldb/lldb.xcodeproj/project.pbxproj
+++ b/lldb/lldb.xcodeproj/project.pbxproj
@@ -2459,7 +2459,6 @@
isa = PBXProject;
buildConfigurationList = 1DEB91EF08733DB70010E9CD /* Build configuration list for PBXProject "lldb" */;
compatibilityVersion = "Xcode 3.1";
- developmentRegion = English;
hasScannedForEncodings = 1;
knownRegions = (
en,
diff --git a/lldb/source/Host/common/Host.cpp b/lldb/source/Host/common/Host.cpp
index a51fa3d6def..c00c87f5ef7 100644
--- a/lldb/source/Host/common/Host.cpp
+++ b/lldb/source/Host/common/Host.cpp
@@ -402,6 +402,13 @@ void
Host::ThreadCreated (const char *thread_name)
{
}
+
+void
+Host::Backtrace (Stream &strm, uint32_t max_frames)
+{
+ // TODO: Is there a way to backtrace the current process on linux?
+}
+
#endif
struct HostThreadCreateInfo
diff --git a/lldb/source/Host/macosx/Host.mm b/lldb/source/Host/macosx/Host.mm
index 7233b951d1a..b9e1171f3b9 100644
--- a/lldb/source/Host/macosx/Host.mm
+++ b/lldb/source/Host/macosx/Host.mm
@@ -9,10 +9,13 @@
#include "lldb/Host/Host.h"
+#include <execinfo.h>
#include <libproc.h>
+#include <stdio.h>
#include <sys/proc.h>
#include <sys/stat.h>
#include <sys/types.h>
+#include <unistd.h>
#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/Communication.h"
@@ -772,3 +775,33 @@ Host::OpenFileInExternalEditor (const FileSpec &file_spec, uint32_t line_no)
return true;
}
+
+
+void
+Host::Backtrace (Stream &strm, uint32_t max_frames)
+{
+ char backtrace_path[] = "/tmp/lldb-backtrace-tmp-XXXXXX";
+ int backtrace_fd = ::mkstemp (backtrace_path);
+ if (backtrace_fd != -1)
+ {
+ std::vector<void *> frame_buffer (max_frames, NULL);
+ int count = ::backtrace (&frame_buffer[0], frame_buffer.size());
+ ::backtrace_symbols_fd (&frame_buffer[0], count, backtrace_fd);
+
+ const off_t buffer_size = ::lseek(backtrace_fd, 0, SEEK_CUR);
+
+ if (::lseek(backtrace_fd, 0, SEEK_SET) == 0)
+ {
+ char *buffer = (char *)::malloc (buffer_size);
+ if (buffer)
+ {
+ ssize_t bytes_read = ::read (backtrace_fd, buffer, buffer_size);
+ if (bytes_read > 0)
+ strm.Write(buffer, bytes_read);
+ ::free (buffer);
+ }
+ }
+ ::close (backtrace_fd);
+ ::unlink (backtrace_path);
+ }
+}
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
index 89b723849fc..394b55231a8 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
@@ -199,13 +199,13 @@ GDBRemoteCommunication::SendContinuePacketAndWaitForResponse
log->Printf ("GDBRemoteCommunication::%s ()", __FUNCTION__);
Mutex::Locker locker(m_sequence_mutex);
-// ScopedValueChanger<bool> restore_running_to_false (m_is_running, false);
StateType state = eStateRunning;
if (SendPacket(payload, packet_length) == 0)
state = eStateInvalid;
- m_is_running.SetValue (true, eBroadcastAlways);
+ BroadcastEvent(eBroadcastBitRunPacketSent, NULL);
+ m_is_running.SetValue (true, eBroadcastNever);
while (state == eStateRunning)
{
@@ -357,7 +357,7 @@ GDBRemoteCommunication::SendContinuePacketAndWaitForResponse
if (log)
log->Printf ("GDBRemoteCommunication::%s () => %s", __FUNCTION__, StateAsCString(state));
response.SetFilePos(0);
- m_is_running.SetValue (false, eBroadcastOnChange);
+ m_is_running.SetValue (false, eBroadcastAlways);
return state;
}
@@ -858,16 +858,3 @@ GDBRemoteCommunication::DeallocateMemory (addr_t addr, uint32_t timeout_seconds)
return false;
}
-bool
-GDBRemoteCommunication::WaitForIsRunning (uint32_t timeout_sec)
-{
- TimeValue timeout;
- if (timeout_sec)
- {
- timeout = TimeValue::Now();
- timeout.OffsetWithSeconds (timeout_sec);
- }
- return m_is_running.WaitForValueEqualTo (true, &timeout, NULL);
-}
-
-
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
index e7ef38ab1e0..0434d8fb736 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
@@ -34,6 +34,10 @@ class GDBRemoteCommunication :
public lldb_private::Communication
{
public:
+ enum
+ {
+ eBroadcastBitRunPacketSent = kLoUserBroadcastBit
+ };
//------------------------------------------------------------------
// Constructors and Destructors
//------------------------------------------------------------------
@@ -203,9 +207,6 @@ public:
}
bool
- WaitForIsRunning (uint32_t timeout_sec);
-
- bool
GetHostInfo (uint32_t timeout_seconds);
bool
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index e7a879bd5a5..083ef95a1f6 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -878,10 +878,20 @@ ProcessGDBRemote::DoResume ()
{
Error error;
ProcessGDBRemoteLog::LogIf (GDBR_LOG_PROCESS, "ProcessGDBRemote::Resume()");
- m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncContinue, new EventDataBytes (m_continue_packet.GetData(), m_continue_packet.GetSize()));
- const uint32_t timedout_sec = 1;
- if (m_gdb_comm.WaitForIsRunning (timedout_sec) == false)
- error.SetErrorString("Resume timed out.");
+
+ Listener listener ("gdb-remote.resume-packet-sent");
+ if (listener.StartListeningForEvents (&m_gdb_comm, GDBRemoteCommunication::eBroadcastBitRunPacketSent))
+ {
+ EventSP event_sp;
+ TimeValue timeout;
+ timeout = TimeValue::Now();
+ timeout.OffsetWithSeconds (5);
+ m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncContinue, new EventDataBytes (m_continue_packet.GetData(), m_continue_packet.GetSize()));
+
+ if (listener.WaitForEvent (&timeout, event_sp) == false)
+ error.SetErrorString("Resume timed out.");
+ }
+
return error;
}
@@ -1206,7 +1216,7 @@ ProcessGDBRemote::DoDestroy ()
SetExitStatus(-1, "process killed");
StringExtractorGDBRemote response;
- if (m_gdb_comm.SendPacketAndWaitForResponse("k", response, 2, false))
+ if (m_gdb_comm.SendPacketAndWaitForResponse("k", response, 1, false))
{
log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS);
if (log)
diff --git a/lldb/tools/debugserver/debugserver.xcodeproj/project.pbxproj b/lldb/tools/debugserver/debugserver.xcodeproj/project.pbxproj
index 3e8a4f84947..01d487b289d 100644
--- a/lldb/tools/debugserver/debugserver.xcodeproj/project.pbxproj
+++ b/lldb/tools/debugserver/debugserver.xcodeproj/project.pbxproj
@@ -372,7 +372,6 @@
isa = PBXProject;
buildConfigurationList = 1DEB914E08733D8E0010E9CD /* Build configuration list for PBXProject "debugserver" */;
compatibilityVersion = "Xcode 3.1";
- developmentRegion = English;
hasScannedForEncodings = 1;
knownRegions = (
English,
diff --git a/lldb/tools/debugserver/source/DNBLog.cpp b/lldb/tools/debugserver/source/DNBLog.cpp
index d99e415f37e..52aa0815275 100644
--- a/lldb/tools/debugserver/source/DNBLog.cpp
+++ b/lldb/tools/debugserver/source/DNBLog.cpp
@@ -21,6 +21,7 @@ static int g_verbose = 0;
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
+#include <sys/time.h>
#include <unistd.h>
#include <mach/mach.h>
#include <pthread.h>
@@ -166,7 +167,27 @@ _DNBLogThreaded (const char *format, ...)
if (arg_msg != NULL)
{
- _DNBLog (DNBLOG_FLAG_THREADED, "%u [%4.4x/%4.4x]: %s", ++g_message_id, getpid(), mach_thread_self(), arg_msg);
+ static struct timeval g_timeval = { 0 , 0 };
+ static struct timeval tv;
+ static struct timeval delta;
+ gettimeofday(&tv, NULL);
+ if (g_timeval.tv_sec == 0)
+ {
+ delta.tv_sec = 0;
+ delta.tv_usec = 0;
+ }
+ else
+ {
+ timersub (&tv, &g_timeval, &delta);
+ }
+ g_timeval = tv;
+ _DNBLog (DNBLOG_FLAG_THREADED, "%u +%u.%06u sec [%4.4x/%4.4x]: %s",
+ ++g_message_id,
+ delta.tv_sec,
+ delta.tv_usec,
+ getpid(),
+ mach_thread_self(),
+ arg_msg);
free (arg_msg);
}
}
@@ -191,7 +212,27 @@ _DNBLogThreadedIf (uint32_t log_bit, const char *format, ...)
if (arg_msg != NULL)
{
- _DNBLog (DNBLOG_FLAG_THREADED, "%u [%4.4x/%4.4x]: %s", ++g_message_id, getpid(), mach_thread_self(), arg_msg);
+ static struct timeval g_timeval = { 0 , 0 };
+ static struct timeval tv;
+ static struct timeval delta;
+ gettimeofday(&tv, NULL);
+ if (g_timeval.tv_sec == 0)
+ {
+ delta.tv_sec = 0;
+ delta.tv_usec = 0;
+ }
+ else
+ {
+ timersub (&tv, &g_timeval, &delta);
+ }
+ g_timeval = tv;
+ _DNBLog (DNBLOG_FLAG_THREADED, "%u +%u.%06u sec [%4.4x/%4.4x]: %s",
+ ++g_message_id,
+ delta.tv_sec,
+ delta.tv_usec,
+ getpid(),
+ mach_thread_self(),
+ arg_msg);
free (arg_msg);
}
}
OpenPOWER on IntegriCloud