[nemiver/gtk2-branch] Introduce Loc (code location) type
- From: Dodji Seketeli <dodji src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [nemiver/gtk2-branch] Introduce Loc (code location) type
- Date: Thu, 21 Apr 2011 22:30:20 +0000 (UTC)
commit bb8b6872be5d32e895e7ed2497fd16a4af88c31f
Author: Dodji Seketeli <dodji seketeli org>
Date: Thu Apr 21 22:02:08 2011 +0200
Introduce Loc (code location) type
* src/common/Makefile.am: Add nmv-loc.h to build system.
* src/common/nmv-loc.h: New file.
* src/dbgengine/nmv-i-debugger.h (IDebugger::set_breakpoint):
New overload that takes an instance of Loc.
* src/dbgengine/nmv-debugger-utils.h (null_default_slot)
(null_disass_slot, null_breakpoints_slot): New declarations.
* src/dbgengine/nmv-debugger-utils.cc (null_default_slot)
(null_disass_slot, null_breakpoints_slot): New definitions.
* src/dbgengine/nmv-gdb-engine.cc (location_to_string): New
helpers to serialize instance of Loc.
(OnBreakpointHandler::handle): Call the argument callback slot
when the command was "set-breakpoint".
(GDBEngine::set_breakpoint): New overload definition that takes an
instance of Loc in argument, as well as callback slot.
(null_disass_slot): Remove this from here.
* src/dbgengine/nmv-gdb-engine.h (GDBEngine::set_breakpoint): New
overload declaration.
src/common/Makefile.am | 3 +-
src/common/nmv-loc.h | 158 +++++++++++++++++++++++++++++++++++
src/dbgengine/nmv-debugger-utils.cc | 21 +++++
src/dbgengine/nmv-debugger-utils.h | 12 +++
src/dbgengine/nmv-gdb-engine.cc | 151 ++++++++++++++++++++++++++++++++--
src/dbgengine/nmv-gdb-engine.h | 8 ++-
src/dbgengine/nmv-i-debugger.h | 12 +++
7 files changed, 357 insertions(+), 8 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..277331f
--- /dev/null
+++ b/src/common/nmv-loc.h
@@ -0,0 +1,158 @@
+//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.m_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;
+ }
+
+ SourceLoc (const SourceLoc &a)
+ : Loc (a)
+ {
+ m_file_path = a.m_file_path;
+ m_line_number = a.m_line_number;
+ }
+
+ 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;
+ }
+
+ FunctionLoc (const FunctionLoc &a)
+ : Loc (a),
+ m_function_name (a.m_function_name)
+ {
+ }
+
+ 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;
+ }
+
+ AddressLoc (const AddressLoc &a)
+ : Loc (a),
+ m_address (a.m_address)
+ {
+ }
+
+ 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..ea95e89 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 ());
@@ -3778,6 +3868,61 @@ GDBEngine::continue_to_position (const UString &a_path,
a_cookie));
}
+/// 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,
@@ -4861,12 +5006,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..da48b39 100644
--- a/src/dbgengine/nmv-gdb-engine.h
+++ b/src/dbgengine/nmv-gdb-engine.h
@@ -328,11 +328,17 @@ public:
gint a_line_num,
const UString &a_cookie) ;
+ 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,
diff --git a/src/dbgengine/nmv-i-debugger.h b/src/dbgengine/nmv-i-debugger.h
index 55823a8..eb75fbd 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,12 @@ public:
gint a_line_num,
const UString &a_cookie="") = 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= "",
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]