[nemiver] Update state when thread id changes.
- From: Dodji Seketeli <dodji src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [nemiver] Update state when thread id changes.
- Date: Tue, 11 Aug 2009 18:45:31 +0000 (UTC)
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]