[nemiver] Update state when thread id changes.



commit 71910f8da1531107c890b1eb5aa1315867609d17
Author: Dodji Seketeli <dodji redhat com>
Date:   Tue Aug 11 16:40:16 2009 +0200

    Update state when thread id changes.
    
    	* src/dbgengine/nmv-gdb-engine.cc:
    	(GDBEngine::Priv::cur_thread_num,
    	 GDBEngine::Priv::cur_frame_address): New attributes.
    	(GDBEngine::Priv::Priv): On thread stop, record the current frame
    	address. Do the same on thread selection, and when threads are
    	listed.
    	(GDBEngine::Priv::queue_command,
    	 GDBEngine::Priv::list_frames): Move the code of
    	GDBEngine::queue_command and GDBEngine::list_frames here.
    	(GDBEngine::Priv::on_thread_selected_signal,
    	 GDBEngine::Priv::on_stopped_signal,
    	 GDBEngine::Priv::on_frames_listed_signal): New event handlers.
    	(OnThreadSelectedHandler::can_handle): Be ready to better detect
    	When a thread is selected.
    	(OnFramesListedHandler::do_handle): Record frame address here.
    	FIXME: this is redundant with what's done in
    	on_frames_listed_signal.
    	(GDBEngine::get_current_frame_address,
    	 GDBEngine::get_mi_thread_and_frame_location,
    	 GDBEngine::get_mi_thread_location,
    	 GDBEngine::get_current_thread): New entry points.
    	(GDBEngine::queue_command,
    	 GDBEngine::list_frames): Tunnel these to
    	GDBEngine::Priv::queue_command and GDBEngine::Priv::list_frames.
    	Also did various cosmetic cleanups.
    	* src/dbgengine/nmv-gdb-engine.h:
    	(GDBEngine::get_current_frame_address,
    	 GDBEngine::set_current_frame_address,
    	 GDBEngine::get_mi_thread_location,
    	 GDBEngine::get_current_thread): Declare these.
    	* src/dbgengine/nmv-i-debugger.h:
    	(IDebugger::get_current_thread): New entry point.

 src/dbgengine/nmv-gdb-engine.cc |  179 ++++++++++++++++++++++++++++++++++++---
 src/dbgengine/nmv-gdb-engine.h  |   10 ++
 src/dbgengine/nmv-i-debugger.h  |    2 +
 3 files changed, 179 insertions(+), 12 deletions(-)
---
diff --git a/src/dbgengine/nmv-gdb-engine.cc b/src/dbgengine/nmv-gdb-engine.cc
index 6a57951..fa8d1d4 100644
--- a/src/dbgengine/nmv-gdb-engine.cc
+++ b/src/dbgengine/nmv-gdb-engine.cc
@@ -119,6 +119,8 @@ public:
     OutputHandlerList output_handler_list;
     IDebugger::State state;
     int cur_frame_level;
+    int cur_thread_num;
+    UString cur_frame_address;
     ILangTraitSafePtr lang_trait;
     UString debugger_full_path;
     GDBMIParser gdbmi_parser;
@@ -420,6 +422,7 @@ public:
         error_buffer_status (DEFAULT),
         state (IDebugger::NOT_STARTED),
         cur_frame_level (0),
+        cur_thread_num (1),
         gdbmi_parser (GDBMIParser::BROKEN_MODE)
     {
         gdb_stdout_signal.connect (sigc::mem_fun
@@ -431,6 +434,16 @@ public:
 
         state_changed_signal.connect (sigc::mem_fun
                 (*this, &Priv::on_state_changed_signal));
+
+        thread_selected_signal.connect (sigc::mem_fun
+               (*this, &Priv::on_thread_selected_signal));
+
+        stopped_signal.connect (sigc::mem_fun
+               (*this, &Priv::on_stopped_signal));
+
+        frames_listed_signal.connect (sigc::mem_fun
+               (*this, &Priv::on_frames_listed_signal));
+
     }
 
     void free_resources ()
@@ -700,6 +713,43 @@ public:
         return false;
     }
 
+    bool queue_command (const Command &a_command)
+    {
+        bool result (false);
+        THROW_IF_FAIL (is_gdb_running ());
+        LOG_DD ("queuing command: '" << a_command.value () << "'");
+        queued_commands.push_back (a_command);
+        if (!line_busy && started_commands.empty ()) {
+            result = issue_command (*queued_commands.begin (), true);
+            queued_commands.erase (queued_commands.begin ());
+        }
+        return result;
+    }
+
+    void list_frames (int a_low_frame,
+                      int a_high_frame,
+                      const UString &a_cookie)
+    {
+        LOG_FUNCTION_SCOPE_NORMAL_DD;
+        string low, high, stack_window, cmd_str;
+
+        if (a_low_frame >= 0)
+            low = UString::from_int (a_low_frame).raw ();
+        if (a_high_frame >= 0)
+            high = UString::from_int (a_high_frame).raw ();
+
+        if (!low.empty () && !high.empty ())
+            stack_window = low + " " + high;
+
+        cmd_str = (stack_window.empty ())
+                  ? "-stack-list-frames"
+                  : "-stack-list-frames " + stack_window;
+
+        queue_command (Command ("list-frames",
+                                cmd_str,
+                                a_cookie));
+    }
+
 
     bool on_gdb_stdout_has_data_signal (Glib::IOCondition a_cond)
     {
@@ -842,6 +892,49 @@ public:
         state = a_state;
     }
 
+    void on_thread_selected_signal (unsigned a_thread_id,
+                                    const IDebugger::Frame * const a_frame,
+                                    const UString &/*a_cookie*/)
+    {
+        LOG_FUNCTION_SCOPE_NORMAL_DD;
+        NEMIVER_TRY
+
+        cur_thread_num = a_thread_id;
+        if (a_frame)
+            cur_frame_level = a_frame->level ();
+
+        NEMIVER_CATCH_NOX
+    }
+
+    void on_stopped_signal (IDebugger::StopReason,
+                            bool a_has_frame,
+                            const IDebugger::Frame &,
+                            int,
+                            int,
+                            const UString &a_cookie)
+    {
+        LOG_FUNCTION_SCOPE_NORMAL_DD;
+        NEMIVER_TRY
+
+        if (a_has_frame)
+            // List frames so that we can get the @ of the current frame.
+            list_frames (0, 0, a_cookie);
+
+        NEMIVER_CATCH_NOX
+    }
+
+    void on_frames_listed_signal (const vector<IDebugger::Frame> &a_frames,
+                                  const UString &)
+    {
+        LOG_FUNCTION_SCOPE_NORMAL_DD;
+        NEMIVER_TRY
+
+        if (!a_frames.empty () && a_frames[0].level () == 0)
+            cur_frame_address = a_frames[0].address ();
+
+        NEMIVER_CATCH_NOX
+    }
+
     bool breakpoint_has_failed (const CommandAndOutput &a_in)
     {
         if (a_in.has_command ()
@@ -1250,8 +1343,23 @@ struct OnThreadSelectedHandler : OutputHandler {
         THROW_IF_FAIL (m_engine);
         if (a_in.output ().has_result_record ()
             && a_in.output ().result_record ().thread_id_got_selected ()) {
+            thread_id = a_in.output ().result_record ().thread_id ();
             return true;
         }
+        if (a_in.output ().has_out_of_band_record ()) {
+            list<Output::OutOfBandRecord>::const_iterator it;
+            for (it = a_in.output ().out_of_band_records ().begin ();
+                 it != a_in.output ().out_of_band_records ().end ();
+                 ++it) {
+                if (it->thread_id ()) {
+                    thread_id = it->thread_id ();
+                    return false; // GDB is broken currently
+                                  // for this. So return false
+                                  // for now. We'll be able to return
+                                  // true later.;
+                }
+            }
+        }
         return false;
     }
 
@@ -1400,6 +1508,13 @@ struct OnFramesListedHandler : OutputHandler {
     void do_handle (CommandAndOutput &a_in)
     {
         LOG_FUNCTION_SCOPE_NORMAL_DD;
+
+        if (!a_in.output ().result_record ().call_stack ().empty ()
+            && a_in.output ().result_record ().call_stack ()[0].level ()
+                == 0)
+            m_engine->set_current_frame_address
+            (a_in.output ().result_record ().call_stack ()[0].address ());
+
         m_engine->frames_listed_signal ().emit
             (a_in.output ().result_record ().call_stack (),
              a_in.command ().cookie ());
@@ -2564,12 +2679,52 @@ void
 GDBEngine::set_current_frame_level (int a_level)
 {
     LOG_FUNCTION_SCOPE_NORMAL_DD;
-    THROW_IF_FAIL (m_priv);
+
 
     LOG_DD ("cur frame level: " << (int) a_level);
     m_priv->cur_frame_level = a_level;
 }
 
+const UString&
+GDBEngine::get_current_frame_address () const
+{
+    LOG_FUNCTION_SCOPE_NORMAL_DD;
+
+
+    return m_priv->cur_frame_address;
+}
+
+void
+GDBEngine::set_current_frame_address (const UString &a_address)
+{
+    LOG_FUNCTION_SCOPE_NORMAL_DD;
+
+
+    m_priv->cur_frame_address = a_address;
+}
+
+void
+GDBEngine::get_mi_thread_and_frame_location (UString &a_str) const
+{
+    LOG_FUNCTION_SCOPE_NORMAL_DD;
+
+    UString frame_level =
+        "--frame " + UString::from_int (get_current_frame_level ());
+
+    a_str = "--thread " + UString::from_int (get_current_thread ())
+            + " " + frame_level;
+
+    LOG_DD ("a_str: " << a_str);
+}
+
+void
+GDBEngine::get_mi_thread_location (UString &a_str) const
+{
+    LOG_FUNCTION_SCOPE_NORMAL_DD;
+    a_str = "--thread " + UString::from_int (get_current_thread ());
+    LOG_DD ("a_str: " << a_str);
+}
+
 void
 GDBEngine::init_output_handlers ()
 {
@@ -3075,16 +3230,7 @@ GDBEngine::execute_command (const Command &a_command)
 bool
 GDBEngine::queue_command (const Command &a_command)
 {
-    bool result (false);
-    THROW_IF_FAIL (m_priv && m_priv->is_gdb_running ());
-    LOG_DD ("queuing command: '" << a_command.value () << "'");
-    m_priv->queued_commands.push_back (a_command);
-    if (!m_priv->line_busy && m_priv->started_commands.empty ()) {
-        result = m_priv->issue_command (*m_priv->queued_commands.begin (),
-                                        true);
-        m_priv->queued_commands.erase (m_priv->queued_commands.begin ());
-    }
-    return result;
+    return m_priv->queue_command (a_command);
 }
 
 bool
@@ -3482,13 +3628,22 @@ GDBEngine::select_thread (unsigned int a_thread_id,
                           const UString &a_cookie)
 {
     LOG_FUNCTION_SCOPE_NORMAL_DD;
-    THROW_IF_FAIL (m_priv);
+
     THROW_IF_FAIL (a_thread_id);
     queue_command (Command ("select-thread", "-thread-select "
                             + UString::from_int (a_thread_id),
                             a_cookie));
 }
 
+unsigned int
+GDBEngine::get_current_thread () const
+{
+    LOG_FUNCTION_SCOPE_NORMAL_DD;
+
+
+    return m_priv->cur_thread_num;
+}
+
 
 void
 GDBEngine::choose_function_overload (int a_overload_number,
diff --git a/src/dbgengine/nmv-gdb-engine.h b/src/dbgengine/nmv-gdb-engine.h
index 2e0d905..7bd46af 100644
--- a/src/dbgengine/nmv-gdb-engine.h
+++ b/src/dbgengine/nmv-gdb-engine.h
@@ -290,6 +290,14 @@ public:
 
     void set_current_frame_level (int);
 
+    const UString& get_current_frame_address () const;
+
+    void set_current_frame_address (const UString &a_address);
+
+    void get_mi_thread_location (UString &a_str) const;
+
+    void get_mi_thread_and_frame_location (UString &a_str) const;
+
     void step_in (const UString &a_cookie) ;
 
     void step_out (const UString &a_cookie) ;
@@ -348,6 +356,8 @@ public:
     void select_thread (unsigned int a_thread_id,
                         const UString &a_cookie) ;
 
+    unsigned int get_current_thread () const;
+
     void delete_breakpoint (gint a_break_num,
                             const UString &a_cookie) ;
 
diff --git a/src/dbgengine/nmv-i-debugger.h b/src/dbgengine/nmv-i-debugger.h
index 27b7738..d0bafa0 100644
--- a/src/dbgengine/nmv-i-debugger.h
+++ b/src/dbgengine/nmv-i-debugger.h
@@ -1072,6 +1072,8 @@ public:
     virtual void select_thread (unsigned int a_thread_id,
                                 const UString &a_cookie="") = 0;
 
+    virtual unsigned int get_current_thread () const = 0;
+
     virtual void select_frame (int a_frame_id,
                                const UString &a_cookie="") = 0;
 



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