[nemiver] Don't ignore "thread-selected" async records



commit 5cde81f9d6173a24e899220b07d5875c85ee44a8
Author: Dodji Seketeli <dodji redhat com>
Date:   Tue Aug 11 16:13:04 2009 +0200

    Don't ignore "thread-selected" async records
    
    	* src/dbgengine/nmv-gdbmi-parser.h:
    	(GDBMI::parse_thread_selected_async_output): Declare New entry point.
    	* src/dbgengine/nmv-gdbmi-parser.cc:
    	(GDBMI::parse_thread_selected_async_output): Implement it.
    	(GDBMIParser::parse_out_of_band_record): Support parsing
    	thread-selected asynchronous record. Various cleanups.
    	* src/dbgengine/nmv-dbg-common.h:
    	(OutOfBandRecord::clear): Set default thread id value to -1.

 src/dbgengine/nmv-dbg-common.h    |    2 +-
 src/dbgengine/nmv-gdbmi-parser.cc |   96 ++++++++++++++++++++++++++++++------
 src/dbgengine/nmv-gdbmi-parser.h  |    8 +++
 3 files changed, 89 insertions(+), 17 deletions(-)
---
diff --git a/src/dbgengine/nmv-dbg-common.h b/src/dbgengine/nmv-dbg-common.h
index 742c3d7..7723bbd 100644
--- a/src/dbgengine/nmv-dbg-common.h
+++ b/src/dbgengine/nmv-dbg-common.h
@@ -312,7 +312,7 @@ public:
             m_has_frame = false ;
             m_frame.clear () ;
             m_breakpoint_number = 0 ;
-            m_thread_id = 0 ;
+            m_thread_id = -1;
             m_signal_type.clear () ;
         }
     };//end class OutOfBandRecord
diff --git a/src/dbgengine/nmv-gdbmi-parser.cc b/src/dbgengine/nmv-gdbmi-parser.cc
index 37352e0..f6639ae 100644
--- a/src/dbgengine/nmv-gdbmi-parser.cc
+++ b/src/dbgengine/nmv-gdbmi-parser.cc
@@ -180,6 +180,7 @@ const char* PREFIX_REGISTER_VALUES = "register-values=";
 const char* PREFIX_MEMORY_VALUES = "addr=";
 const char* PREFIX_RUNNING_ASYNC_OUTPUT = "*running,";
 const char* PREFIX_STOPPED_ASYNC_OUTPUT = "*stopped,";
+const char* PREFIX_THREAD_SELECTED_ASYNC_OUTPUT = "=thread-selected,";
 const char* PREFIX_NAME = "name=\"";
 const char* PREFIX_VARIABLE_DELETED = "ndeleted=\"";
 const char* NDELETED = "ndeleted";
@@ -1255,7 +1256,8 @@ GDBMIParser::parse_stopped_async_output (UString::size_type a_from,
 
     if (m_priv->index_passed_end (cur)) {return false;}
 
-    if (m_priv->input.raw ().compare (cur, strlen (PREFIX_STOPPED_ASYNC_OUTPUT),
+    if (m_priv->input.raw ().compare (cur,
+                                      strlen (PREFIX_STOPPED_ASYNC_OUTPUT),
                                       PREFIX_STOPPED_ASYNC_OUTPUT)) {
         LOG_PARSING_ERROR2 (cur);
         return false;
@@ -1324,11 +1326,12 @@ GDBMIParser::parse_running_async_output (UString::size_type a_from,
 {
     LOG_FUNCTION_SCOPE_NORMAL_D (GDBMI_PARSING_DOMAIN);
 
-    UString::size_type cur=a_from;
+    UString::size_type cur=a_from,
+                       prefix_len = strlen (PREFIX_RUNNING_ASYNC_OUTPUT);
 
     if (m_priv->index_passed_end (cur)) {return false;}
 
-    if (m_priv->input.raw ().compare (cur, strlen (PREFIX_RUNNING_ASYNC_OUTPUT),
+    if (m_priv->input.raw ().compare (cur, prefix_len,
                                       PREFIX_RUNNING_ASYNC_OUTPUT)) {
         LOG_PARSING_ERROR_MSG2 (cur, "was expecting : '*running,'");
         return false;
@@ -1355,6 +1358,47 @@ GDBMIParser::parse_running_async_output (UString::size_type a_from,
 }
 
 bool
+GDBMIParser::parse_thread_selected_async_output (UString::size_type a_from,
+                                                 UString::size_type &a_to,
+                                                 int &a_thread_id)
+{
+    LOG_FUNCTION_SCOPE_NORMAL_D (GDBMI_PARSING_DOMAIN);
+
+    UString::size_type cur = a_from,
+                       prefix_len =
+                           strlen (PREFIX_THREAD_SELECTED_ASYNC_OUTPUT);
+
+    if (m_priv->index_passed_end (cur)) {return false;}
+
+    if (m_priv->input.raw ().compare (cur, prefix_len,
+                                      PREFIX_THREAD_SELECTED_ASYNC_OUTPUT)) {
+        LOG_PARSING_ERROR_MSG2 (cur, "was expecting : '=thread-selected,'");
+        return false;
+    }
+    cur += prefix_len;
+    if (m_priv->index_passed_end (cur)) {return false;}
+
+    UString name, value;
+    if (!parse_attribute (cur, cur, name, value)) {
+        LOG_PARSING_ERROR_MSG2 (cur, "was expecting an attribute");
+        return false;
+    }
+    if (name != "id" && name != "thread-id") {
+        LOG_PARSING_ERROR_MSG2 (cur, "was expecting attribute 'thread-id' or 'id'");
+        return false;
+    }
+    unsigned thread_id = atoi (value.c_str ());
+    if (!thread_id) {
+        LOG_PARSING_ERROR_MSG2 (cur, "was expecting a non null thread-id");
+        return false;
+    }
+
+    a_thread_id = thread_id;
+    a_to = cur;
+    return true;
+}
+
+bool
 GDBMIParser::parse_attribute (UString::size_type a_from,
                               UString::size_type &a_to,
                               UString &a_name,
@@ -1591,18 +1635,10 @@ GDBMIParser::parse_out_of_band_record (UString::size_type a_from,
 
         while (m_priv->index_passed_end (cur)
                && isspace (RAW_CHAR_AT (cur))) {++cur;}
-    } else if (RAW_CHAR_AT (cur) == '=') {
-        //this is a notification sent by gdb. For now, the only one
-        //I have seen like this is of the form:
-        //'=thread-created,id=1',
-        //and the notification ends with a '\n' character.
-        //Of course it is not documented
-        //Let's ignore this by now
-        while (RAW_CHAR_AT (cur) != '\n') {++cur;}
-        ++cur;//consume the '\n' character
-    }
-
-    if (!m_priv->input.raw ().compare (cur, strlen (PREFIX_STOPPED_ASYNC_OUTPUT),
+    }
+
+    if (!m_priv->input.raw ().compare (cur,
+                                       strlen (PREFIX_STOPPED_ASYNC_OUTPUT),
                                        PREFIX_STOPPED_ASYNC_OUTPUT)) {
         map<UString, UString> attrs;
         bool got_frame (false);
@@ -1633,7 +1669,8 @@ GDBMIParser::parse_out_of_band_record (UString::size_type a_from,
         goto end;
     }
 
-    if (!m_priv->input.raw ().compare (cur, strlen (PREFIX_RUNNING_ASYNC_OUTPUT),
+    if (!m_priv->input.raw ().compare (cur,
+                                       strlen (PREFIX_RUNNING_ASYNC_OUTPUT),
                                        PREFIX_RUNNING_ASYNC_OUTPUT)) {
         int thread_id;
         if (!parse_running_async_output (cur, cur, thread_id)) {
@@ -1646,6 +1683,33 @@ GDBMIParser::parse_out_of_band_record (UString::size_type a_from,
         goto end;
     }
 
+    if (!m_priv->input.raw ().compare
+                            (cur,
+                             strlen (PREFIX_THREAD_SELECTED_ASYNC_OUTPUT),
+                                     PREFIX_THREAD_SELECTED_ASYNC_OUTPUT)) {
+        int thread_id;
+        if (!parse_thread_selected_async_output (cur, cur, thread_id)) {
+            LOG_PARSING_ERROR_MSG2 (cur,
+                                    "could not parse the expected "
+                                    "running async output");
+            return false;
+        }
+        record.thread_id (thread_id);
+        goto end;
+    }
+
+    if (RAW_CHAR_AT (cur) == '=' || RAW_CHAR_AT (cur) == '*') {
+       //this is an unknown async notification sent by gdb.
+       //For now, the only one
+       //I have seen like this is of the form:
+       //'=thread-created,id=1',
+       //and the notification ends with a '\n' character.
+       //Of course it is not documented
+       //Let's ignore this by now
+       while (RAW_CHAR_AT (cur) != '\n') {++cur;}
+       ++cur;//consume the '\n' character
+    }
+
 end:
 
     while (!m_priv->index_passed_end (cur)
diff --git a/src/dbgengine/nmv-gdbmi-parser.h b/src/dbgengine/nmv-gdbmi-parser.h
index 2eb3b9b..d886302 100644
--- a/src/dbgengine/nmv-gdbmi-parser.h
+++ b/src/dbgengine/nmv-gdbmi-parser.h
@@ -454,6 +454,14 @@ public:
                                      UString::size_type &a_to,
                                      int &a_thread_id);
 
+    /// parse GBBMI async output that says which thread was selected in
+    /// in the inferior
+    /// the string looks like:
+    /// =thread-selected,thread-id="<thread-id"
+    bool parse_thread_selected_async_output (UString::size_type a_from,
+                                             UString::size_type &a_to,
+                                             int &a_thread_id);
+
     bool parse_attribute (UString::size_type a_from,
                           UString::size_type &a_to,
                           UString &a_name,



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]