[Lldb-commits] [lldb] r120793 - in /lldb/trunk: include/lldb/Host/Host.h lldb.xcodeproj/project.pbxproj source/Host/common/Host.cpp source/Host/macosx/Host.mm source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp tools/debugserver/debugserver.xcodeproj/project.pbxproj tools/debugserver/source/DNBLog.cpp

Greg Clayton gclayton at apple.com
Thu Dec 2 22:02:24 PST 2010


Author: gclayton
Date: Fri Dec  3 00:02:24 2010
New Revision: 120793

URL: http://llvm.org/viewvc/llvm-project?rev=120793&view=rev
Log:
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.


Modified:
    lldb/trunk/include/lldb/Host/Host.h
    lldb/trunk/lldb.xcodeproj/project.pbxproj
    lldb/trunk/source/Host/common/Host.cpp
    lldb/trunk/source/Host/macosx/Host.mm
    lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
    lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
    lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
    lldb/trunk/tools/debugserver/debugserver.xcodeproj/project.pbxproj
    lldb/trunk/tools/debugserver/source/DNBLog.cpp

Modified: lldb/trunk/include/lldb/Host/Host.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Host/Host.h?rev=120793&r1=120792&r2=120793&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Host/Host.h (original)
+++ lldb/trunk/include/lldb/Host/Host.h Fri Dec  3 00:02:24 2010
@@ -315,7 +315,6 @@
     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 @@
     static bool
     OpenFileInExternalEditor (const FileSpec &file_spec, uint32_t line_no);
 
+    static void
+    Backtrace (Stream &strm, uint32_t max_frames);
 };
 
 } // namespace lldb_private

Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=120793&r1=120792&r2=120793&view=diff
==============================================================================
--- lldb/trunk/lldb.xcodeproj/project.pbxproj (original)
+++ lldb/trunk/lldb.xcodeproj/project.pbxproj Fri Dec  3 00:02:24 2010
@@ -2459,7 +2459,6 @@
 			isa = PBXProject;
 			buildConfigurationList = 1DEB91EF08733DB70010E9CD /* Build configuration list for PBXProject "lldb" */;
 			compatibilityVersion = "Xcode 3.1";
-			developmentRegion = English;
 			hasScannedForEncodings = 1;
 			knownRegions = (
 				en,

Modified: lldb/trunk/source/Host/common/Host.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/common/Host.cpp?rev=120793&r1=120792&r2=120793&view=diff
==============================================================================
--- lldb/trunk/source/Host/common/Host.cpp (original)
+++ lldb/trunk/source/Host/common/Host.cpp Fri Dec  3 00:02:24 2010
@@ -402,6 +402,13 @@
 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

Modified: lldb/trunk/source/Host/macosx/Host.mm
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/macosx/Host.mm?rev=120793&r1=120792&r2=120793&view=diff
==============================================================================
--- lldb/trunk/source/Host/macosx/Host.mm (original)
+++ lldb/trunk/source/Host/macosx/Host.mm Fri Dec  3 00:02:24 2010
@@ -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 @@
       
     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);
+    }
+}

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp?rev=120793&r1=120792&r2=120793&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp Fri Dec  3 00:02:24 2010
@@ -199,13 +199,13 @@
         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 @@
     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 @@
     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);
-}
-    
-

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h?rev=120793&r1=120792&r2=120793&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h Fri Dec  3 00:02:24 2010
@@ -34,6 +34,10 @@
     public lldb_private::Communication
 {
 public:
+    enum
+    {
+        eBroadcastBitRunPacketSent = kLoUserBroadcastBit
+    };
     //------------------------------------------------------------------
     // Constructors and Destructors
     //------------------------------------------------------------------
@@ -203,9 +207,6 @@
     }
     
     bool
-    WaitForIsRunning (uint32_t timeout_sec);
-    
-    bool
     GetHostInfo (uint32_t timeout_seconds);
 
     bool 

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=120793&r1=120792&r2=120793&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp Fri Dec  3 00:02:24 2010
@@ -878,10 +878,20 @@
 {
     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 @@
     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)

Modified: lldb/trunk/tools/debugserver/debugserver.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/debugserver.xcodeproj/project.pbxproj?rev=120793&r1=120792&r2=120793&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/debugserver.xcodeproj/project.pbxproj (original)
+++ lldb/trunk/tools/debugserver/debugserver.xcodeproj/project.pbxproj Fri Dec  3 00:02:24 2010
@@ -372,7 +372,6 @@
 			isa = PBXProject;
 			buildConfigurationList = 1DEB914E08733D8E0010E9CD /* Build configuration list for PBXProject "debugserver" */;
 			compatibilityVersion = "Xcode 3.1";
-			developmentRegion = English;
 			hasScannedForEncodings = 1;
 			knownRegions = (
 				English,

Modified: lldb/trunk/tools/debugserver/source/DNBLog.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/DNBLog.cpp?rev=120793&r1=120792&r2=120793&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/DNBLog.cpp (original)
+++ lldb/trunk/tools/debugserver/source/DNBLog.cpp Fri Dec  3 00:02:24 2010
@@ -21,6 +21,7 @@
 #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 @@
 
         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 @@
 
         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);
         }
     }





More information about the lldb-commits mailing list