[nemiver/jump-to] 560235 Initial support of "jump to"
- From: Dodji Seketeli <dodji src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [nemiver/jump-to] 560235 Initial support of "jump to"
- Date: Sun, 10 Apr 2011 11:25:36 +0000 (UTC)
commit 4b3d4116fd9fe7f24f6625810175d6ca36d6b8df
Author: Dodji Seketeli <dodji seketeli org>
Date: Fri Mar 25 09:50:50 2011 +0100
560235 Initial support of "jump to"
* src/common/nmv-loc.h: New location type declarations.
* src/common/Makefile.am: Add it to build system.
* src/dbgengine/nmv-i-debugger.h (IDebugger::DefaultSlot)
(IDebugger::BreakpointsSlot, IDebugger::LocSlot): New slot
typedefs.
(IDebugger::jump_to_position): New entry point.
(IDebugger::set_breakpoint, IDebugger::enable_breakpoint): New
overloads taking callback slots.
* src/dbgengine/nmv-gdb-engine.h (GDBEngine::jump_to_position)
(GDBEngine::set_breakpoint, GDBEngine::enable_breakpoint): Declare
these functions.
* src/dbgengine/nmv-gdb-engine.cc (location_to_string): New
function overloads to generate a GDB location string for each type
of location.
(OnBreakpointHandler::do_handle): Support callback slots for
commands 'set-breakpoint', '-break-enable' and 'jump-to-position'.
(GDBEngine::jump_to_position): Define new function.
(GDBEngine::set_breakpoint): Add new overload that takes a
callback slot and an instance of location type.
(GDBEngine::enable_breakpoint): Likewise. Rewrite the other
overload in terms of this one.
(null_disass_slot): Move this to nmv-debugger-utils.cc
* src/dbgengine/nmv-debugger-utils.h ((null_default_slot,
null_disass_slot, null_breakpoints_slot): Declare new functions.
* src/dbgengine/nmv-debugger-utils.cc (null_default_slot)
(null_disass_slot, null_breakpoints_slot): Define new functions.
* src/persp/dbgperspective/nmv-dbg-perspective.cc
(DBGPerspective::on_jump_to_current_location_action)
(DBGPerspective::on_jump_and_break_to_current_location_action)
(DBGPerspective::on_break_before_jump)
(DBGPerspective::do_jump_to_current_location)
(DBGPerspective::do_jump_and_break_to_current_location)
(DBGPerspective::jump_to_location): New functions.
(DBGPerspective::on_debugger_breakpoints_set_signal): Minor style
cleanup.
(DBGPerspective::init_actions): Add
JumpToCurrentLocationMenuItemAction and
JumpAndBreakToCurrentLocationMenuItemAction actions.
(DBGPerspective::get_contextual_menu): Add two new menu items for
actions JumpToCurrentLocationMenuItemAction and
JumpAndBreakToCurrentLocationMenuItemAction.
src/common/Makefile.am | 3 +-
src/common/nmv-loc.h | 136 +++++++++++++
src/dbgengine/nmv-debugger-utils.cc | 21 ++
src/dbgengine/nmv-debugger-utils.h | 12 ++
src/dbgengine/nmv-gdb-engine.cc | 231 +++++++++++++++++++++-
src/dbgengine/nmv-gdb-engine.h | 15 ++-
src/dbgengine/nmv-i-debugger.h | 19 ++
src/persp/dbgperspective/nmv-dbg-perspective.cc | 177 +++++++++++++++++-
8 files changed, 597 insertions(+), 17 deletions(-)
---
diff --git a/src/common/Makefile.am b/src/common/Makefile.am
index eaa09d0..5b61d90 100644
--- a/src/common/Makefile.am
+++ b/src/common/Makefile.am
@@ -41,7 +41,8 @@ $(h)/nmv-sql-statement.h \
$(h)/nmv-insert-statement.h \
$(h)/nmv-delete-statement.h \
$(h)/nmv-proc-utils.h \
-$(h)/nmv-proc-mgr.h
+$(h)/nmv-proc-mgr.h \
+$(h)/nmv-loc.h
libnemivercommon_la_SOURCES= $(headers) \
$(h)/nmv-ustring.cc \
diff --git a/src/common/nmv-loc.h b/src/common/nmv-loc.h
new file mode 100644
index 0000000..67749a9
--- /dev/null
+++ b/src/common/nmv-loc.h
@@ -0,0 +1,136 @@
+//Author: Dodji Seketeli
+/*
+ *This file is part of the Nemiver project
+ *
+ *Nemiver is free software; you can redistribute
+ *it and/or modify it under the terms of
+ *the GNU General Public License as published by the
+ *Free Software Foundation; either version 2,
+ *or (at your option) any later version.
+ *
+ *Nemiver is distributed in the hope that it will
+ *be useful, but WITHOUT ANY WARRANTY;
+ *without even the implied warranty of
+ *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *See the GNU General Public License for more details.
+ *
+ *You should have received a copy of the
+ *GNU General Public License along with Nemiver;
+ *see the file COPYING.
+ *If not, write to the Free Software Foundation,
+ *Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *See COPYRIGHT file copyright information.
+ */
+
+#ifndef __NEMIVER_LOC_H__
+#define __NEMIVER_LOC_H__
+
+#include "nmv-ustring.h"
+#include "nmv-address.h"
+#include "nmv-api-macros.h"
+
+/// \file
+/// The declaration of source, function and addresses related location
+/// types. For now, it's only the debugging engine backend that knows
+/// how to serialize a location into a location string.
+
+NEMIVER_BEGIN_NAMESPACE (nemiver)
+NEMIVER_BEGIN_NAMESPACE (common)
+
+/// The base type presenting a location.
+class NEMIVER_API Loc
+{
+ public:
+ /// The different possible kinds of locations.
+ enum Kind
+ {
+ UNDEFINED_LOC_KIND,
+ SOURCE_LOC_KIND,
+ FUNCTION_LOC_KIND,
+ ADDRESS_LOC_KIND
+ };
+
+ protected:
+ Kind m_kind;
+
+ Loc ()
+ : m_kind (UNDEFINED_LOC_KIND)
+ {
+ }
+
+ Loc (const Loc &a)
+ {
+ m_kind = a.kind ();
+ }
+
+ public:
+ Kind kind () const {return m_kind;}
+ virtual ~Loc () {};
+}; // end class Loc
+
+/// A source location.
+///
+/// It encapsulates a file name and a line number
+/// in that file.
+class NEMIVER_API SourceLoc : public Loc
+{
+ UString m_file_path;
+ int m_line_number;
+
+ public:
+ SourceLoc (const UString &a_file_path,
+ int a_line_number)
+ : m_file_path (a_file_path),
+ m_line_number (a_line_number)
+ {
+ m_kind = SOURCE_LOC_KIND;
+ }
+
+ const UString& file_path () const {return m_file_path;}
+ void file_path (const UString &a) {m_file_path = a;}
+ int line_number () const {return m_line_number;}
+ void line_number (int a) {m_line_number = a;}
+};// end class SourceLoc;
+
+/// A function location.
+///
+/// It encapsulates the location of a function.
+class NEMIVER_API FunctionLoc : public Loc
+{
+ UString m_function_name;
+
+ public:
+ FunctionLoc (const UString &a_function_name)
+ : m_function_name (a_function_name)
+ {
+ m_kind = FUNCTION_LOC_KIND;
+
+ }
+
+ const UString& function_name () const {return m_function_name;}
+ void function_name (const UString &a) {m_function_name = a;}
+};
+
+/// An address location.
+///
+/// It encapslates an address.
+class NEMIVER_API AddressLoc : public Loc
+{
+ Address m_address;
+
+ public:
+ AddressLoc (const Address &a)
+ : m_address (a)
+ {
+ m_kind = ADDRESS_LOC_KIND;
+ }
+
+ const Address& address () const {return m_address;}
+ void address (const Address &a) {m_address = a;}
+};
+
+NEMIVER_END_NAMESPACE (common)
+NEMIVER_END_NAMESPACE (nemiver)
+
+#endif //__NEMIVER_LOC_H__
diff --git a/src/dbgengine/nmv-debugger-utils.cc b/src/dbgengine/nmv-debugger-utils.cc
index 4e78dd1..9c97815 100644
--- a/src/dbgengine/nmv-debugger-utils.cc
+++ b/src/dbgengine/nmv-debugger-utils.cc
@@ -29,6 +29,10 @@
NEMIVER_BEGIN_NAMESPACE (nemiver)
NEMIVER_BEGIN_NAMESPACE (debugger_utils)
+/// \name Definitions of no-op callback slots that can used by client
+/// code.
+///
+/// @{
void
null_const_variable_slot (const IDebugger::VariableSafePtr &)
{
@@ -54,6 +58,23 @@ null_frame_args_slot (const map<int, IDebugger::VariableList> &)
{
}
+void
+null_default_slot ()
+{
+}
+
+void
+null_disass_slot (const common::DisassembleInfo &,
+ const std::list<common::Asm> &)
+{
+}
+
+void
+null_breakpoints_slot (const map<int, IDebugger::Breakpoint>&)
+{
+}
+///@}
+
/// Generate a string of of white spaces.
/// \param a_nb_ws the number of white spaces to generate
/// \param a_ws_str the output string the white spaces are
diff --git a/src/dbgengine/nmv-debugger-utils.h b/src/dbgengine/nmv-debugger-utils.h
index 75026d7..479d13c 100644
--- a/src/dbgengine/nmv-debugger-utils.h
+++ b/src/dbgengine/nmv-debugger-utils.h
@@ -32,6 +32,9 @@
NEMIVER_BEGIN_NAMESPACE (nemiver)
NEMIVER_BEGIN_NAMESPACE (debugger_utils)
+/// \name Declarations of no-op callback slots
+///
+/// @{
void null_const_variable_slot (const IDebugger::VariableSafePtr &);
void null_const_variable_list_slot (const IDebugger::VariableList &);
@@ -42,6 +45,15 @@ void null_frame_vector_slot (const vector<IDebugger::Frame> &);
void null_frame_args_slot (const map<int, IDebugger::VariableList> &);
+void null_default_slot ();
+
+void null_disass_slot (const common::DisassembleInfo &,
+ const std::list<common::Asm> &);
+
+void null_breakpoints_slot (const map<int, IDebugger::Breakpoint>&);
+
+/// @}
+
void dump_variable_value (IDebugger::VariableSafePtr a_var,
int a_indent_num,
std::ostringstream &a_os,
diff --git a/src/dbgengine/nmv-gdb-engine.cc b/src/dbgengine/nmv-gdb-engine.cc
index 3f7b184..7123bd5 100644
--- a/src/dbgengine/nmv-gdb-engine.cc
+++ b/src/dbgengine/nmv-gdb-engine.cc
@@ -57,6 +57,8 @@ using nemiver::debugger_utils::null_const_variable_slot;
using nemiver::debugger_utils::null_const_variable_list_slot;
using nemiver::debugger_utils::null_frame_vector_slot;
using nemiver::debugger_utils::null_frame_args_slot;
+using nemiver::debugger_utils::null_disass_slot;
+using nemiver::debugger_utils::null_breakpoints_slot;
NEMIVER_BEGIN_NAMESPACE (nemiver)
@@ -79,6 +81,88 @@ quote_args (const vector<UString> &a_prog_args)
return args;
}
+//**************************************************************
+// <Helper functions to generate a serialized form of location>
+//**************************************************************
+
+/// Generate a location string from a an instance of source location
+/// type.
+///
+/// \param a_loc the source input location
+///
+/// \param a_str the resulting location string
+static void
+location_to_string (const SourceLoc &a_loc,
+ UString &a_str)
+{
+ a_str =
+ a_loc.file_path ()
+ + ":" + UString::from_int (a_loc.line_number ());
+}
+
+/// Generate a location string from a an instance of address location
+/// type.
+///
+/// \param a_loc the input address location
+///
+/// \param a_str the resulting location string
+static void
+location_to_string (const AddressLoc &a_loc,
+ UString &a_str)
+{
+ a_str = "*" + a_loc.address ().to_string ();
+}
+
+/// Generate a location string from a an instance of function location
+/// type.
+///
+/// \param a_loc the input function location
+///
+/// \param a_str the resulting location string
+static void
+location_to_string (const FunctionLoc &a_loc,
+ UString &a_str)
+{
+ a_str = a_loc.function_name ();
+}
+
+/// Generate a location string from a generic instance of location
+/// type.
+///
+/// \param a_loc the input location
+///
+/// \param a_str the resulting location string
+static void
+location_to_string (const Loc &a_loc,
+ UString &a_str)
+{
+ switch (a_loc.kind ()) {
+ case Loc::UNDEFINED_LOC_KIND:
+ THROW ("Should not be reached");
+
+ case Loc::SOURCE_LOC_KIND: {
+ const SourceLoc *loc = static_cast<const SourceLoc*> (&a_loc);
+ location_to_string (*loc, a_str);
+ }
+ break;
+
+ case Loc::FUNCTION_LOC_KIND: {
+ const FunctionLoc *loc = static_cast<const FunctionLoc*> (&a_loc);
+ location_to_string (*loc, a_str);
+ }
+ break;
+
+ case Loc::ADDRESS_LOC_KIND: {
+ const AddressLoc *loc = static_cast<const AddressLoc*> (&a_loc);
+ location_to_string (*loc, a_str);
+ }
+ break;
+ }
+}
+
+//**************************************************************
+// </Helper functions to generate a serialized form of location>
+//**************************************************************
//*************************
//<GDBEngine::Priv struct>
@@ -1330,6 +1414,12 @@ struct OnBreakpointHandler: OutputHandler {
}
} else if (has_breaks) {
LOG_DD ("firing IDebugger::breakpoint_set_signal()");
+ Command &c = a_in.command ();
+ if (c.name () == "set-breakpoint"
+ && c.has_slot ()) {
+ IDebugger::BreakpointsSlot slot = c.get_slot<IDebugger::BreakpointsSlot> ();
+ slot (m_engine->get_cached_breakpoints ());
+ }
m_engine->breakpoints_set_signal ().emit
(m_engine->get_cached_breakpoints (),
a_in.command ().cookie ());
@@ -1614,6 +1704,13 @@ struct OnCommandDoneHandler : OutputHandler {
}
}
+ if (a_in.command ().name () == "-break-enable"
+ && a_in.command ().has_slot ()) {
+ IDebugger::BreakpointsSlot slot =
+ a_in.command ().get_slot<IDebugger::BreakpointsSlot> ();
+ slot (m_engine->get_cached_breakpoints ());
+ }
+
// So, if we are still attached to the target and we receive
// a "DONE" response from GDB, it means we are READY.
// But if we are not attached -- which can mean that the
@@ -1652,7 +1749,13 @@ struct OnRunningHandler : OutputHandler {
void do_handle (CommandAndOutput &a_in)
{
LOG_FUNCTION_SCOPE_NORMAL_DD;
- if (a_in.has_command ()) {}
+
+ Command &c = a_in.command ();
+ if (c.name () == "jump-to-position"
+ && c.has_slot ()) {
+ IDebugger::DefaultSlot s = c.get_slot<IDebugger::DefaultSlot> ();
+ s ();
+ }
m_engine->running_signal ().emit ();
}
};//struct OnRunningHandler
@@ -3778,6 +3881,85 @@ GDBEngine::continue_to_position (const UString &a_path,
a_cookie));
}
+/// Jump to a location in the inferior.
+///
+/// Execution is then resumed from the new location.
+///
+/// \param a_loc the location to jump to
+///
+/// \param a_slot a callback function that is invoked once the jump is
+/// done.
+void
+GDBEngine::jump_to_position (const Loc &a_loc,
+ const DefaultSlot &a_slot)
+{
+ LOG_FUNCTION_SCOPE_NORMAL_DD;
+
+ UString location;
+
+ location_to_string (a_loc, location);
+
+ Command command ("jump-to-position",
+ "-exec-jump " + location);
+ command.set_slot (a_slot);
+ queue_command (command);
+}
+
+/// Set a breakpoint at a location in the inferior.
+///
+/// \param a_loc the location of the breakpoint.
+///
+/// \param a_condition the condition of the breakpoin. If there is no
+/// condition, the argument should be "".
+///
+/// \param a_ignore_count the number of time the breakpoint should be
+/// hit before execution of the inferior is stopped.
+///
+/// \param a_slot a callback slot to be invoked once the breakpoint is
+/// set.
+///
+/// \param a_cookie a string to be passed to
+/// IDebugger::breakpoints_set_signals once that signal emitted as a
+/// result of the breakpoint being set. Note both a_slot and
+/// IDebugger::breakpoint_set_signals are 'called' upon breakpoint
+/// actual setting. Eventually, IDebugger::breakpoints_set_signals
+/// should be dropped, so this whole cookie business would disapear.
+/// We are still in a transitional period.
+void
+GDBEngine::set_breakpoint (const Loc &a_loc,
+ const UString &a_condition,
+ gint a_ignore_count,
+ const BreakpointsSlot &a_slot,
+ const UString &a_cookie)
+{
+ LOG_FUNCTION_SCOPE_NORMAL_DD;
+
+ THROW_IF_FAIL (a_loc.kind () != Loc::UNDEFINED_LOC_KIND);
+
+ UString loc_str;
+
+ location_to_string (a_loc, loc_str);
+
+ UString break_cmd = "-break-insert -f ";
+ if (!a_condition.empty ()) {
+ LOG_DD ("setting breakpoint with condition: " << a_condition);
+ break_cmd += " -c \"" + a_condition + "\"";
+ } else {
+ LOG_DD ("setting breakpoint without condition");
+ }
+
+ bool count_point = (a_ignore_count < 0);
+ if (!count_point)
+ break_cmd += " -i " + UString::from_int (a_ignore_count);
+
+ break_cmd += " " + loc_str;
+ string cmd_name = count_point ? "set-countpoint" : "set-breakpoint";
+
+ Command command (cmd_name, break_cmd, a_cookie);
+ command.set_slot (a_slot);
+ queue_command (command);
+}
+
void
GDBEngine::set_breakpoint (const UString &a_path,
gint a_line_num,
@@ -3837,18 +4019,51 @@ GDBEngine::set_breakpoint (const Address &a_address,
queue_command (Command (cmd_name, break_cmd, a_cookie));
}
+/// Enable a given breakpoint
+///
+/// \param a_break_num the ID of the breakpoint to enable.
+///
+/// \param a_slot a callback slot invoked upon completion of the
+/// command by GDB.
+///
+/// \param a_cookie a string passed as an argument to
+/// IDebugger::breakpoints_set_signal upon completion of the command
+/// by GDB. Note that both a_slot and
+/// IDebugger::breakpoints_set_signal are invoked upon completion of
+/// the command by GDB for now. Eventually only a_slot will be kept;
+/// IDebugger::breakpoints_set_signal will be dropped. We in a
+/// transitional period at the moment.
void
GDBEngine::enable_breakpoint (gint a_break_num,
+ const BreakpointsSlot &a_slot,
const UString &a_cookie)
{
LOG_FUNCTION_SCOPE_NORMAL_DD;
- queue_command (Command ("enable-breakpoint",
- "-break-enable "
- + UString::from_int (a_break_num),
- a_cookie));
+
+ Command command ("enable-breakpoint",
+ "-break-enable "
+ + UString::from_int (a_break_num));
+ command.set_slot (a_slot);
+ queue_command (command);
list_breakpoints (a_cookie);
}
+/// Enable a given breakpoint
+///
+/// \param a_break_num the ID of the breakpoint to enable.
+///
+/// \param a_cookie a string passed as an argument to
+/// IDebugger::breakpoints_set_signal upon completion of the command
+/// by GDB. Eventually this function should be dropped and we should
+/// keep the one above.
+void
+GDBEngine::enable_breakpoint (gint a_break_num,
+ const UString &a_cookie)
+{
+ LOG_FUNCTION_SCOPE_NORMAL_DD;
+ enable_breakpoint (a_break_num, &null_breakpoints_slot, a_cookie);
+}
+
void
GDBEngine::disable_breakpoint (gint a_break_num,
const UString &a_cookie)
@@ -4861,12 +5076,6 @@ GDBEngine::set_memory (size_t a_addr,
}
void
-null_disass_slot (const common::DisassembleInfo &,
- const std::list<common::Asm> &)
-{
-}
-
-void
GDBEngine::disassemble (size_t a_start_addr,
bool a_start_addr_relative_to_pc,
size_t a_end_addr,
diff --git a/src/dbgengine/nmv-gdb-engine.h b/src/dbgengine/nmv-gdb-engine.h
index 964a641..89e9cb9 100644
--- a/src/dbgengine/nmv-gdb-engine.h
+++ b/src/dbgengine/nmv-gdb-engine.h
@@ -328,11 +328,20 @@ public:
gint a_line_num,
const UString &a_cookie) ;
+ void jump_to_position (const Loc &a_loc,
+ const DefaultSlot &a_slot);
+
+ void set_breakpoint (const Loc &a_loc,
+ const UString &a_condition,
+ gint a_ignore_count,
+ const BreakpointsSlot &a_slot,
+ const UString &a_cookie);
+
void set_breakpoint (const UString &a_path,
gint a_line_num,
const UString &a_condition,
gint a_ignore_count,
- const UString &a_cookie) ;
+ const UString &a_cookie);
void set_breakpoint (const UString &a_func_name,
const UString &a_condition,
@@ -345,6 +354,10 @@ public:
const UString &a_cookie);
void enable_breakpoint (gint a_break_num,
+ const BreakpointsSlot &a_slot,
+ const UString &a_cookie = "");
+
+ void enable_breakpoint (gint a_break_num,
const UString &a_cookie="");
void disable_breakpoint (gint a_break_num,
diff --git a/src/dbgengine/nmv-i-debugger.h b/src/dbgengine/nmv-i-debugger.h
index 55823a8..99be184 100644
--- a/src/dbgengine/nmv-i-debugger.h
+++ b/src/dbgengine/nmv-i-debugger.h
@@ -37,6 +37,7 @@
#include "common/nmv-safe-ptr-utils.h"
#include "common/nmv-address.h"
#include "common/nmv-asm-instr.h"
+#include "common/nmv-loc.h"
#include "nmv-i-conf-mgr.h"
using nemiver::common::SafePtr;
@@ -52,6 +53,7 @@ using nemiver::common::AsmInstr;
using nemiver::common::MixedAsmInstr;
using nemiver::common::Asm;
using nemiver::common::DisassembleInfo;
+using nemiver::common::Loc;
using std::vector;
using std::string;
using std::map;
@@ -819,6 +821,10 @@ public:
return false;
}
+ typedef sigc::slot<void> DefaultSlot;
+ typedef sigc::slot<void, const map<int, IDebugger::Breakpoint>&> BreakpointsSlot;
+ typedef sigc::slot<void, Loc&> LocSlot;
+
virtual ~IDebugger () {}
/// \name events you can connect to.
@@ -1115,6 +1121,15 @@ public:
gint a_line_num,
const UString &a_cookie="") = 0;
+ virtual void jump_to_position (const Loc &a_loc,
+ const DefaultSlot &a_slot) = 0;
+
+ virtual void set_breakpoint (const common::Loc &a_loc,
+ const UString &a_condition,
+ gint a_ignore_count,
+ const BreakpointsSlot &a_slot,
+ const UString &a_cookie = "") = 0;
+
virtual void set_breakpoint (const UString &a_path,
gint a_line_num,
const UString &a_condition= "",
@@ -1132,6 +1147,10 @@ public:
const UString &a_cookie = "") = 0;
virtual void enable_breakpoint (gint a_break_num,
+ const BreakpointsSlot &a_slot,
+ const UString &a_cookie="") = 0;
+
+ virtual void enable_breakpoint (gint a_break_num,
const UString &a_cookie="") = 0;
virtual void disable_breakpoint (gint a_break_num,
diff --git a/src/persp/dbgperspective/nmv-dbg-perspective.cc b/src/persp/dbgperspective/nmv-dbg-perspective.cc
index 88ef7d0..d1f5131 100644
--- a/src/persp/dbgperspective/nmv-dbg-perspective.cc
+++ b/src/persp/dbgperspective/nmv-dbg-perspective.cc
@@ -64,6 +64,7 @@
#include "common/nmv-date-utils.h"
#include "common/nmv-str-utils.h"
#include "common/nmv-address.h"
+#include "common/nmv-loc.h"
#include "nmv-sess-mgr.h"
#include "nmv-dbg-perspective.h"
#include "nmv-source-editor.h"
@@ -102,6 +103,7 @@
using namespace std;
using namespace nemiver::common;
+using namespace nemiver::debugger_utils;
using namespace nemiver::ui_utils;
using namespace gtksourceview;
@@ -236,6 +238,10 @@ private:
void on_step_over_asm_action ();
void on_continue_action ();
void on_continue_until_action ();
+ void on_jump_to_current_location_action ();
+ void on_jump_and_break_to_current_location_action ();
+ void on_break_before_jump (const map<int, IDebugger::Breakpoint>&,
+ const Loc &a_loc);
void on_set_breakpoint_action ();
void on_set_breakpoint_using_dialog_action ();
void on_set_watchpoint_using_dialog_action ();
@@ -597,6 +603,9 @@ public:
void step_over_asm ();
void do_continue ();
void do_continue_until ();
+ void do_jump_to_current_location ();
+ void do_jump_and_break_to_current_location ();
+ void jump_to_location (const map<int, IDebugger::Breakpoint>&, const SourceLoc &);
void set_breakpoint_at_current_line_using_dialog ();
void set_breakpoint ();
void set_breakpoint (const UString &a_file,
@@ -1008,7 +1017,6 @@ struct DBGPerspective::Priv {
list<UString> call_expr_history;
list<UString> var_inspector_dialog_history;
-
Priv () :
initialized (false),
reused_session (false),
@@ -1544,6 +1552,56 @@ DBGPerspective::on_continue_until_action ()
NEMIVER_CATCH
}
+/// Callback function invoked when the menu item action "jump to
+/// current location" is activated.
+///
+/// It jumps to the location selected by the user in the source
+/// editor.
+void
+DBGPerspective::on_jump_to_current_location_action ()
+{
+ LOG_FUNCTION_SCOPE_NORMAL_DD;
+
+ NEMIVER_TRY
+ do_jump_to_current_location ();
+ NEMIVER_CATCH
+}
+
+/// Callback function invoked when the menu item action "setting a
+/// breakpoint to current lcoation and jump here" is activated.
+///
+/// It sets a breakpoint to the current location and jumps here. So
+/// is transfered to the location selected by the user in the source
+/// editor and is stopped there.
+void
+DBGPerspective::on_jump_and_break_to_current_location_action ()
+{
+ LOG_FUNCTION_SCOPE_NORMAL_DD;
+
+ NEMIVER_TRY
+ do_jump_and_break_to_current_location ();
+ NEMIVER_CATCH
+}
+
+/// This callback is invoked right after a breakpoint is set as part
+/// of a "set a breakpoint and jump there" process.
+///
+/// So this function jumps to the position given in parameter.
+///
+/// \param a_loc the location to jump to. This is also the location
+/// of the breakpoint that was set previously and which triggered this
+/// callback.
+void
+DBGPerspective::on_break_before_jump (const map<int, IDebugger::Breakpoint> &,
+ const Loc &a_loc)
+{
+ LOG_FUNCTION_SCOPE_NORMAL_DD;
+
+ NEMIVER_TRY;
+ debugger ()->jump_to_position (a_loc, &null_default_slot);
+ NEMIVER_CATCH;
+}
+
void
DBGPerspective::on_toggle_breakpoint_action ()
{
@@ -2518,6 +2576,13 @@ DBGPerspective::on_debugger_command_done_signal (const UString &a_command,
NEMIVER_CATCH
}
+/// Callback function invoked once a breakpoint was set.
+///
+/// \param a_breaks the list of all breakpoints currently set in the inferior.
+///
+/// \param a_cookie a string passed to the IDebugger::set_breakpoint
+/// call that triggered this callback.
+///
void
DBGPerspective::on_debugger_breakpoints_set_signal
(const map<int, IDebugger::Breakpoint> &a_breaks,
@@ -2532,9 +2597,9 @@ DBGPerspective::on_debugger_breakpoints_set_signal
// When the breakpoint is set, it
// will send a 'cookie' along of the form
// "initiallly-disabled#filename.cc#123"
- if (a_cookie.find("initially-disabled") != UString::npos) {
- UString::size_type start_of_file = a_cookie.find('#') + 1;
- UString::size_type start_of_line = a_cookie.rfind('#') + 1;
+ if (a_cookie.find ("initially-disabled") != UString::npos) {
+ UString::size_type start_of_file = a_cookie.find ('#') + 1;
+ UString::size_type start_of_line = a_cookie.rfind ('#') + 1;
UString file = a_cookie.substr (start_of_file,
(start_of_line - 1) - start_of_file);
int line = atoi
@@ -3391,6 +3456,27 @@ DBGPerspective::init_actions ()
false
},
{
+ "JumpToCurrentLocationMenuItemAction",
+ nil_stock_id,
+ _("Jump to cursor"),
+ _("Jump to the currently selected line"),
+ sigc::mem_fun (*this, &DBGPerspective::on_jump_to_current_location_action),
+ ActionEntry::DEFAULT,
+ "",
+ false
+ },
+ {
+ "JumpAndBreakToCurrentLocationMenuItemAction",
+ nil_stock_id,
+ _("Jump and stop to cursor"),
+ _("Sets a breakpoint to the current currently selected line and jump there"),
+ sigc::mem_fun (*this,
+ &DBGPerspective::on_jump_and_break_to_current_location_action),
+ ActionEntry::DEFAULT,
+ "",
+ false
+ },
+ {
"ToggleBreakpointMenuItemAction",
nil_stock_id,
// Depending on the context we will want this string to be
@@ -4763,6 +4849,22 @@ DBGPerspective::get_contextual_menu ()
workbench ().get_ui_manager ()->add_ui
(m_priv->contextual_menu_merge_id,
"/ContextualMenu",
+ "JumpToCurrentLocationMenuItem",
+ "JumpToCurrentLocationMenuItemAction",
+ Gtk::UI_MANAGER_AUTO,
+ false);
+
+ workbench ().get_ui_manager ()->add_ui
+ (m_priv->contextual_menu_merge_id,
+ "/ContextualMenu",
+ "JumpAndBreakToCurrentLocationMenuItem",
+ "JumpAndBreakToCurrentLocationMenuItemAction",
+ Gtk::UI_MANAGER_AUTO,
+ false);
+
+ workbench ().get_ui_manager ()->add_ui
+ (m_priv->contextual_menu_merge_id,
+ "/ContextualMenu",
"StopMenuItem",
"StopMenuItemAction",
Gtk::UI_MANAGER_AUTO,
@@ -6698,6 +6800,73 @@ DBGPerspective::do_continue_until ()
debugger ()->continue_to_position (file_path, current_line);
}
+/// Jump (transfer execution of the inferior) to the location selected
+/// by the user in the source editor.
+void
+DBGPerspective::do_jump_to_current_location ()
+{
+ SourceEditor *editor = get_current_source_editor ();
+ THROW_IF_FAIL (editor);
+
+ int current_line = editor->current_line ();
+ UString file_path;
+ editor->get_file_name (file_path);
+ SourceLoc loc (file_path, current_line);
+ debugger ()->jump_to_position (loc, &null_default_slot);
+}
+
+/// Set a breakpoint to the location selected by the user in the
+/// source editor and jump (transfer execution of the inferior) there.
+void
+DBGPerspective::do_jump_and_break_to_current_location ()
+{
+ THROW_IF_FAIL (m_priv);
+ SourceEditor *editor = get_current_source_editor ();
+ THROW_IF_FAIL (editor);
+
+ int current_line = editor->current_line ();
+ UString file_path;
+ editor->get_file_name (file_path);
+
+ SourceLoc loc (file_path, current_line);
+ bool bp_enabled = false;
+ if (is_breakpoint_set_at_line (file_path,
+ current_line,
+ bp_enabled)) {
+ if (bp_enabled) {
+ debugger ()->jump_to_position (loc, &null_default_slot);
+ } else {
+ const IDebugger::Breakpoint *bp =
+ get_breakpoint (file_path, current_line);
+ debugger ()->enable_breakpoint
+ (bp->number (),
+ sigc::bind
+ (sigc::mem_fun
+ (*this,
+ &DBGPerspective::jump_to_location),
+ loc));
+ }
+ } else {
+ debugger ()->set_breakpoint (loc,
+ /*a_condition=*/"",/*a_ignore_count=*/0,
+ sigc::bind
+ (sigc::mem_fun
+ (*this,
+ &DBGPerspective::on_break_before_jump),
+ loc));
+ }
+}
+
+/// Jump (transfert execution of the inferior) to a given source
+/// location. This is a callback for the
+/// IDebugger::breakpoint_set_signal signal.
+void
+DBGPerspective::jump_to_location (const map<int, IDebugger::Breakpoint>&,
+ const SourceLoc &a_loc)
+{
+ debugger ()->jump_to_position (a_loc, &null_default_slot);
+}
+
void
DBGPerspective::set_breakpoint ()
{
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]