[PATCH] 700248 Support breakpoints with multiple locations



Hello,

Since some time, the GDB Machine Interface that Nemiver uses has
introduced a new way to represent breakpoints that have multiple
locations.  Suppose you set a breakpoint on a function foo (by saying
'break on function foo, in Nemiver speak) that has three overloads, in
C++.  GDB then sets one new kind of breakpoint that has 3 locations;
one location per overload.

Actually each location is more than just a passive location, for it
comes with the property 'enable' that let's you enable/disable the
breakpoint on that location.  So in Nemiver speak, I called each
location a sub-breakpoint.

Thus a breakpoint with multiple location is a top-level breakpoint
that has sub-breakpoints (one for each overload, in the case of foo
above).  Graphically, only the sub-breakpoints are visible breakpoint
items that the user can enable, disable or remove.

The patch below implements this new feature so that Nemiver doesn't
error out now whenever one sets a breakpoint like that now.

Tested and applied to master.

        * src/dbgengine/nmv-i-debugger.h (Breakpoint::{m_sub_breakpoints,
        m_parent_breakpoint}): New members.
        (IDebugger::Breakpoint::number): Change the type of this into a string.  It
        can now be something like "2.1", for a sub-breakpoint of
        breakpoint "2", representing one location of the breakpoint 2 that
        has several locations.
        (IDebugger::Breakpoint::{sub_breakpoint_number, has_multiple_locations,
        append_sub_breakpoint, sub_breakpoints, parent_breakpoint_number,
        is_sub_breakpoint): New methods.
        (IDebugger::{BreakpointsSlot, breakpoints_list_signal,
        breakpoint_set_signal, stopped_signal, enable_breakpoint,
        disable_breakpoint, set_breakpoint_ignore_count,
        set_breakpoint_condition, enable_countpoint, is_countpoint,
        get_cached_breakpoints, get_breakpoint_from_cache,
        delete_breakpoint}): Adjust for use of type of the breakpoint
        number.
        * src/dbgengine/nmv-dbg-common.h
        (Output::ResultRecord::{m_breakpoint, breakpoints}): Adjust
        breakpoint map type.
        * src/dbgengine/nmv-debugger-utils.cc (null_breakpoints_slot): Likewise.
        * src/dbgengine/nmv-debugger-utils.h (null_breakpoints_slot): Likewise.
        * src/dbgengine/nmv-gdb-engine.cc
        (GDBEngine::Priv::{cached_breakpoints, breakpoints_list_signal,
        breakpoints_set_signal, breakpoint_deleted_signal, stopped_signal,
        on_stopped_signal}, OnBreakpointHandler::do_handle). Likewise.
        Also adjust usage of breakpoint number type.
        (OnStoppedHandler::do_handle): Adjust usage of breakpoint number
        type.
        (OnCommandDoneHandler::{flag_breakpoint_as_countpoint,
        do_handle}): Likewise.
        (GDBEngine::{breakpoint_deleted_signal, breakpoints_list_signal,
        stopped_signal, on_stopped_signal, enable_breakpoint,
        disable_breakpoint, set_breakpoint_ignore_count,
        set_breakpoint_condition, enable_countpoint, is_countpoint,
        get_cached_breakpoints, get_breakpoint_from_cache,
        append_breakpoint_to_cache, delete_breakpoint}): Likewise.
        * src/dbgengine/nmv-gdb-engine.h
        (GDGEngine::{breakpoints_list_signal, breakpoints_set_signal,
        breakpoint_deleted_signal, stopped_signal, on_stopped_signal,
        append_breakpoint_to_cache, enable_breakpoint, disable_breakpoint,
        set_breakpoint_ignore_count, set_breakpoint_condition,
        enable_countpoint, is_countpoint, get_cached_breakpoints,
        get_breakpoint_from_cache, delete_breakpoint}):  Likewise.
        * src/dbgengine/nmv-gdbmi-parser.cc
        (GDBMIParser::Priv::skip_blank): New.
        (SKIP_BLANK2): Make this use the new
        GDBMIParser::Priv::skip_blank.
        (GDBMIParser::parse_result_record): Adjust for the use of
        breakpoint number.
        (GDBMIParser::parse_breakpoint_with_one_loc): Renamed
        GDBMIParser::parse_breakpoint into this.  Make this support either
        parsing a sub-breakpoint or not.
        (GDBMIParser::parse_breakpoint): Write a new version of this that
        uses parse_breakpoint_with_one_loc to possibly parse a breakpoint
        with several locations.
        (GDBMIParse::parse_breakpoint_table): Adjust for use of breakpoint
        number.
        * src/dbgengine/nmv-gdbmi-parser.h
        (GDBMIParser::parse_breakpoint_with_one_loc): New entry point.
        (GDBMIParser::parse_breakpoint_table): Adjust for use of
        breakpoint number.
        * src/persp/dbgperspective/nmv-breakpoints-view.cc (BPColumns::id):
        Change the type of the breakpoint id from int to string.
        (BreakpointsView::Priv::update_or_append_breakpoint): New.
        Actually factorized from ...
        (BreakpointsView::Priv::set_breakpoint_condition): ... here.
        Modify this to add/set the sub-breakpoints of a multiple
        breakpoint.
        (BreakpointsView::Priv::{add_breakpoints, breakpoint_list_has_id,
        erase_breakpoint, on_debugger_breakpoints_list_signal,
        on_debugger_stopped_signal, on_debugger_breakpoint_deleted_signal,
        on_debugger_breakpoints_set_signal, on_breakpoint_delete_action,
        on_breakpoint_enable_toggled, on_countpoint_toggled,
        on_breakpoint_ignore_count_edited,
        on_breakpoint_condition_edited})
        (BreakpointsView::set_breakpoints): Adjust for the type of
        breakpoint id.
        (BreakpointsView::Priv::append_breakpoint): Make this return void
        now.  Change it to append sub-breakpoints of a multiple-locations
        breakpoint.  Add comments.
        * src/persp/dbgperspective/nmv-breakpoints-view.h
        (BreakpointsView::set_breakpoints): Adjust for the type of
        breakpoint id.
        * src/persp/dbgperspective/nmv-call-stack.cc
        (CallStack::Priv::on_debugger_stopped_signal): Likewise.
        * src/persp/dbgperspective/nmv-dbg-perspective.cc
        (DBGPerspective::{on_break_before_jump,
        on_debugger_breakpoints_set_signal,
        on_debugger_breakpoints_list_signal,
        on_debugger_breakpoint_deleted_signal, on_debugger_stopped_signal,
        jump_to_location, append_breakpoints, delete_breakpoint,
        toggle_breakpoint_enabled, delete_visual_breakpoint,
        get_frame_breakpoints_address_range, record_and_save_session,
        execute_program, re_initialize_set_breakpoints, get_breakpoint,
        delete_visual_breakpoints, apply_decorations_to_source,
        apply_decorations_to_asm} DBGPerspective::Priv::{breakpoints}):
        Likewise.
        (DBGPerspective::append_breakpoint): Append sub-breakpoints of a
        multiple-locations breakpoint.
        * src/persp/dbgperspective/nmv-dbg-perspective.h
        (DBGPerspective::{append_breakpoint, delete_breakpoint}): Adjust
        for the type of breakpoint id.
        * src/persp/dbgperspective/nmv-expr-monitor.cc
        (ExprMonitor::Priv::on_stopped_signal): Likewise.
        * src/persp/dbgperspective/nmv-local-vars-inspector.cc
        (LocalVarsInspector::Priv::on_stopped_signal): Likewise.
        * src/persp/dbgperspective/nmv-memory-view.cc
        (MemoryView::Priv::on_stopped_signal): Likewise.
        * src/persp/dbgperspective/nmv-registers-view.cc
        (RegistersView::Priv::on_debugger_stopped): Likewise.
        * src/persp/dbgperspective/nmv-thread-list.cc
        (ThreadList::Priv::on_debugger_stopped_signal): Likewise.
        * tests/test-breakpoint.cc (test_main): Set a breakpoint on the
        overloaded Person::overload method, to test this new "breakpoint
        with multiple locations" feature support.
        (on_breakpoints_set_signal): Adjust for the use of breakpoint id
        type.
        (on_stopped_signal): Likewise.  Support stopping on
        'Person::overload' overloaded method, and continuing from there.
        (on_program_finished_signal): Update the number of breakpoint
        stops expected.
        * tests/test-core.cc (on_stopped_signal): Adjust for the use of
        breakpoint id type.
        * tests/test-deref.cc (on_stopped_signal): Likewise.
        * tests/test-disassemble.cc (on_stopped_signal): Likewise.
        * tests/test-gdbmi.cc (gv_breakpoint3): New breakpoint with
        multiple location MI output.
        (test_breakpoint): Test the parsing of the new gv_breakpoint3.
        (test_breakpoint_table): Adjust for the use of breakpoint id type.
        * tests/test-local-vars-list.cc (on_stopped_signal): Adjust for
        the use of breakpoint id type.
        * tests/test-pretty-print.cc (on_stopped_signal): Likewise.
        * tests/test-threads.cc (on_stopped_signal): Likewise.
        * tests/test-types.cc (on_stopped_signal): Likewise.
        * tests/test-var-list.cc (on_stopped_signal): Likewise.
        * tests/test-var-path-expr.cc (on_breakpoints_set_signal)
        (on_stopped_signal): Likewise.
        * tests/test-var-walker.cc (on_stopped_signal): Likewise.
        * tests/test-variable-format.cc (on_stopped_signal): Likewise.
        * tests/test-varobj-walker.cc (on_stopped_signal): Likewise.
        * tests/test-vars.cc (on_stopped_signal): Likewise.
        * tests/test-watchpoint.cc (on_breakpoints_set_signal)
        (on_stopped_signal): Likewise.
---
 src/dbgengine/nmv-dbg-common.h                     |   6 +-
 src/dbgengine/nmv-debugger-utils.cc                |   2 +-
 src/dbgengine/nmv-debugger-utils.h                 |   2 +-
 src/dbgengine/nmv-gdb-engine.cc                    | 111 +++++++-------
 src/dbgengine/nmv-gdb-engine.h                     |  32 ++---
 src/dbgengine/nmv-gdbmi-parser.cc                  | 119 ++++++++++++---
 src/dbgengine/nmv-gdbmi-parser.h                   |   7 +-
 src/dbgengine/nmv-i-debugger.h                     |  89 +++++++++---
 src/persp/dbgperspective/nmv-breakpoints-view.cc   | 159 ++++++++++++---------
 src/persp/dbgperspective/nmv-breakpoints-view.h    |   2 +-
 src/persp/dbgperspective/nmv-call-stack.cc         |   2 +-
 src/persp/dbgperspective/nmv-dbg-perspective.cc    |  96 +++++++------
 src/persp/dbgperspective/nmv-dbg-perspective.h     |   4 +-
 src/persp/dbgperspective/nmv-expr-monitor.cc       |   2 +-
 .../dbgperspective/nmv-local-vars-inspector.cc     |   2 +-
 src/persp/dbgperspective/nmv-memory-view.cc        |   2 +-
 src/persp/dbgperspective/nmv-registers-view.cc     |   2 +-
 src/persp/dbgperspective/nmv-thread-list.cc        |   2 +-
 tests/test-breakpoint.cc                           |  18 ++-
 tests/test-core.cc                                 |   2 +-
 tests/test-deref.cc                                |   2 +-
 tests/test-disassemble.cc                          |   2 +-
 tests/test-gdbmi.cc                                |  24 +++-
 tests/test-local-vars-list.cc                      |   2 +-
 tests/test-pretty-print.cc                         |   2 +-
 tests/test-threads.cc                              |   2 +-
 tests/test-types.cc                                |   2 +-
 tests/test-var-list.cc                             |   2 +-
 tests/test-var-path-expr.cc                        |   6 +-
 tests/test-var-walker.cc                           |   2 +-
 tests/test-variable-format.cc                      |   2 +-
 tests/test-varobj-walker.cc                        |   2 +-
 tests/test-vars.cc                                 |   2 +-
 tests/test-watchpoint.cc                           |   6 +-
 34 files changed, 446 insertions(+), 273 deletions(-)

diff --git a/src/dbgengine/nmv-dbg-common.h b/src/dbgengine/nmv-dbg-common.h
index bf62626..20d0eb1 100644
--- a/src/dbgengine/nmv-dbg-common.h
+++ b/src/dbgengine/nmv-dbg-common.h
@@ -418,7 +418,7 @@ public:
 
     private:
         Kind m_kind;
-        map<int, IDebugger::Breakpoint> m_breakpoints;
+        map<string, IDebugger::Breakpoint> m_breakpoints;
         map<UString, UString> m_attrs;
 
         //call stack listed members
@@ -563,11 +563,11 @@ public:
         Kind kind () const {return m_kind;}
         void kind (Kind a_in) {m_kind = a_in;}
 
-        const map<int, IDebugger::Breakpoint>& breakpoints () const
+        const map<string, IDebugger::Breakpoint>& breakpoints () const
         {
             return m_breakpoints;
         }
-        map<int, IDebugger::Breakpoint>& breakpoints () {return m_breakpoints;}
+        map<string, IDebugger::Breakpoint>& breakpoints () {return m_breakpoints;}
 
         map<UString, UString>& attrs () {return m_attrs;}
         const map<UString, UString>& attrs () const {return m_attrs;}
diff --git a/src/dbgengine/nmv-debugger-utils.cc b/src/dbgengine/nmv-debugger-utils.cc
index c3b1ad0..e33e507 100644
--- a/src/dbgengine/nmv-debugger-utils.cc
+++ b/src/dbgengine/nmv-debugger-utils.cc
@@ -70,7 +70,7 @@ null_disass_slot (const common::DisassembleInfo &,
 }
 
 void
-null_breakpoints_slot (const map<int, IDebugger::Breakpoint>&)
+null_breakpoints_slot (const map<string, IDebugger::Breakpoint>&)
 {
 }
 ///@}
diff --git a/src/dbgengine/nmv-debugger-utils.h b/src/dbgengine/nmv-debugger-utils.h
index e2c1804..fab9ce0 100644
--- a/src/dbgengine/nmv-debugger-utils.h
+++ b/src/dbgengine/nmv-debugger-utils.h
@@ -50,7 +50,7 @@ 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 null_breakpoints_slot (const map<string, IDebugger::Breakpoint>&);
 
 /// @}
 
diff --git a/src/dbgengine/nmv-gdb-engine.cc b/src/dbgengine/nmv-gdb-engine.cc
index 39bd609..c709231 100644
--- a/src/dbgengine/nmv-gdb-engine.cc
+++ b/src/dbgengine/nmv-gdb-engine.cc
@@ -210,7 +210,7 @@ public:
     list<Command> queued_commands;
     list<Command> started_commands;
     bool line_busy;
-    map<int, IDebugger::Breakpoint> cached_breakpoints;
+    map<string, IDebugger::Breakpoint> cached_breakpoints;
     enum InBufferStatus {
         DEFAULT,
         FILLING,
@@ -267,11 +267,11 @@ public:
     mutable sigc::signal<void> inferior_re_run_signal;
 
     mutable sigc::signal<void,
-                         const map<int, IDebugger::Breakpoint>&,
+                         const map<string, IDebugger::Breakpoint>&,
                          const UString&> breakpoints_list_signal;
 
     mutable sigc::signal<void,
-                         const std::map<int, IDebugger::Breakpoint>&,
+                         const std::map<string, IDebugger::Breakpoint>&,
                          const UString& /*cookie*/> breakpoints_set_signal;
 
     mutable sigc::signal<void,
@@ -280,7 +280,7 @@ public:
 
     mutable sigc::signal<void,
                          const IDebugger::Breakpoint&,
-                         int,
+                         const string&,
                          const UString&> breakpoint_deleted_signal;
 
     mutable sigc::signal<void, const IDebugger::Breakpoint&, int>
@@ -291,7 +291,7 @@ public:
 
     mutable sigc::signal<void, IDebugger::StopReason,
                          bool, const IDebugger::Frame&,
-                         int, int, const UString&> stopped_signal;
+                         int, const string&, const UString&> stopped_signal;
 
     mutable sigc::signal<void,
                          const list<int>,
@@ -1235,7 +1235,7 @@ public:
                             bool a_has_frame,
                             const IDebugger::Frame &,
                             int,
-                            int,
+                            const string&,
                             const UString &a_cookie)
     {
         LOG_FUNCTION_SCOPE_NORMAL_DD;
@@ -1535,7 +1535,7 @@ struct OnBreakpointHandler: OutputHandler {
             // We are getting this reply b/c we did set a breakpoint;
             // be aware that sometimes GDB can actually set multiple
             // breakpoints as a result.
-            const map<int, IDebugger::Breakpoint> &bps =
+            const map<string, IDebugger::Breakpoint> &bps =
                 a_in.output ().result_record ().breakpoints ();
 
             Command &c = a_in.command ();
@@ -1561,10 +1561,10 @@ struct OnBreakpointHandler: OutputHandler {
             tmp = tmp.erase (0, 13);
             if (tmp.size () == 0) {return;}
             tmp.chomp ();
-            int bkpt_number = atoi (tmp.c_str ());
-            if (bkpt_number) {
-                map<int, IDebugger::Breakpoint>::iterator iter;
-                map<int, IDebugger::Breakpoint> &breaks =
+            string bkpt_number = tmp;
+            if (!bkpt_number.empty ()) {
+                map<string, IDebugger::Breakpoint>::iterator iter;
+                map<string, IDebugger::Breakpoint> &breaks =
                                         m_engine->get_cached_breakpoints ();
                 iter = breaks.find (bkpt_number);
                 if (iter != breaks.end ()) {
@@ -1577,7 +1577,7 @@ struct OnBreakpointHandler: OutputHandler {
             } else {
                 LOG_ERROR ("Got deleted breakpoint number '"
                            << tmp
-                           << "', but that's not a well formed number dude.");
+                           << "', but that's not a well formed number, dude.");
             }
         } else if (has_breaks) {
             LOG_DD ("firing IDebugger::breakpoints_list_signal(), after command: "
@@ -1644,7 +1644,7 @@ struct OnStoppedHandler: OutputHandler {
                 << "Cookie was '" << a_in.command ().cookie () << "'");
 
         int thread_id = m_out_of_band_record.thread_id ();
-        int breakpoint_number = -1;
+        string breakpoint_number;
         IDebugger::StopReason reason = m_out_of_band_record.stop_reason ();
         if (reason == IDebugger::BREAKPOINT_HIT
             || reason == IDebugger::WATCHPOINT_SCOPE)
@@ -1792,10 +1792,10 @@ struct OnCommandDoneHandler : OutputHandler {
         m_engine (a_engine)
     {}
 
-    bool flag_breakpoint_as_countpoint (int a_break_num,
+    bool flag_breakpoint_as_countpoint (const string& a_break_num,
                                         bool a_yes)
     {
-        typedef map<int, IDebugger::Breakpoint> BPMap;
+        typedef map<string, IDebugger::Breakpoint> BPMap;
         BPMap &bp_cache = m_engine->get_cached_breakpoints ();
         BPMap::const_iterator nil = bp_cache.end ();
 
@@ -1848,9 +1848,9 @@ struct OnCommandDoneHandler : OutputHandler {
         if (a_in.command ().name () == "enable-countpoint"
             || a_in.command ().name () == "disable-countpoint") {
             if (a_in.command ().name () == "enable-countpoint") {
-                flag_breakpoint_as_countpoint (a_in.command ().tag2 (), true);
+                flag_breakpoint_as_countpoint (a_in.command ().tag0 (), true);
             } else if (a_in.command ().name () == "disable-countpoint") {
-                flag_breakpoint_as_countpoint (a_in.command ().tag2 (), false);
+                flag_breakpoint_as_countpoint (a_in.command ().tag0 (), false);
             }
 
             m_engine->breakpoints_list_signal ().emit
@@ -3618,20 +3618,20 @@ GDBEngine::inferior_re_run_signal () const
     return m_priv->inferior_re_run_signal;
 }
 
-sigc::signal<void, const IDebugger::Breakpoint&, int, const UString&>&
+sigc::signal<void, const IDebugger::Breakpoint&, const string&, const UString&>&
 GDBEngine::breakpoint_deleted_signal () const
 {
     return m_priv->breakpoint_deleted_signal;
 }
 
-sigc::signal<void, const map<int, IDebugger::Breakpoint>&, const UString&>&
+sigc::signal<void, const map<string, IDebugger::Breakpoint>&, const UString&>&
 GDBEngine::breakpoints_list_signal () const
 {
     return m_priv->breakpoints_list_signal;
 }
 
 sigc::signal<void,
-             const std::map<int, IDebugger::Breakpoint>&,
+             const std::map<string, IDebugger::Breakpoint>&,
              const UString& /*cookie*/>&
 GDBEngine::breakpoints_set_signal () const
 {
@@ -3646,7 +3646,7 @@ GDBEngine::got_overloads_choice_signal () const
 
 sigc::signal<void, IDebugger::StopReason,
              bool, const IDebugger::Frame&,
-             int, int, const UString&>&
+             int, const string&, const UString&>&
 GDBEngine::stopped_signal () const
 {
     return m_priv->stopped_signal;
@@ -3914,17 +3914,12 @@ GDBEngine::on_got_target_info_signal (int a_pid, const UString &a_exe_path)
 
 void
 GDBEngine::on_stopped_signal (IDebugger::StopReason a_reason,
-                              bool a_has_frame,
-                              const IDebugger::Frame &a_frame,
-                              int a_thread_id,
-                              int a_bkpt_num,
-                              const UString &a_cookie)
+                              bool /*a_has_frame*/,
+                              const IDebugger::Frame &/*a_frame*/,
+                              int /*a_thread_id*/,
+                              const string& /*a_bkpt_num*/,
+                              const UString &/*a_cookie*/)
 {
-    if (a_has_frame || a_frame.line ()
-        || a_thread_id || a_cookie.empty ()
-        || a_bkpt_num) {
-        //keep compiler happy
-    }
 
     NEMIVER_TRY
 
@@ -4682,15 +4677,14 @@ GDBEngine::set_breakpoint (const Address &a_address,
 /// IDebugger::breakpoints_set_signal will be dropped.  We in a
 /// transitional period at the moment.
 void
-GDBEngine::enable_breakpoint (gint a_break_num,
+GDBEngine::enable_breakpoint (const string &a_break_num,
                               const BreakpointsSlot &a_slot,
                               const UString &a_cookie)
 {
     LOG_FUNCTION_SCOPE_NORMAL_DD;
     
     Command command ("enable-breakpoint",
-                     "-break-enable "
-                     + UString::from_int (a_break_num));
+                     "-break-enable " + a_break_num);
     command.set_slot (a_slot);
     queue_command (command);
     list_breakpoints (a_cookie);
@@ -4705,7 +4699,7 @@ GDBEngine::enable_breakpoint (gint a_break_num,
 /// by GDB.  Eventually this function should be dropped and we should
 /// keep the one above.
 void
-GDBEngine::enable_breakpoint (gint a_break_num,
+GDBEngine::enable_breakpoint (const string &a_break_num,
                               const UString &a_cookie)
 {
     LOG_FUNCTION_SCOPE_NORMAL_DD;
@@ -4713,35 +4707,34 @@ GDBEngine::enable_breakpoint (gint a_break_num,
 }
 
 void
-GDBEngine::disable_breakpoint (gint a_break_num,
+GDBEngine::disable_breakpoint (const string &a_break_num,
                                const UString &a_cookie)
 {
     LOG_FUNCTION_SCOPE_NORMAL_DD;
     UString cur_frame;
     queue_command (Command ("disable-breakpoint",
-                            "-break-disable "
-                            + UString::from_int (a_break_num),
+                            "-break-disable " + a_break_num,
                             a_cookie));
     list_breakpoints (a_cookie);
 }
 
 void
-GDBEngine::set_breakpoint_ignore_count (gint a_break_num,
+GDBEngine::set_breakpoint_ignore_count (const string &a_break_num,
                                         gint a_ignore_count,
                                         const UString &a_cookie)
 {
     LOG_FUNCTION_SCOPE_NORMAL_DD;
 
-    RETURN_IF_FAIL (a_break_num >= 0 && a_ignore_count >= 0);
+    RETURN_IF_FAIL (!a_break_num.empty () && a_ignore_count >= 0);
 
     Command command ("set-breakpoint-ignore-count",
-                     "-break-after " + UString::from_int (a_break_num)
+                     "-break-after " + a_break_num
                      + " " + UString::from_int (a_ignore_count),
                      a_cookie);
     queue_command (command);
     list_breakpoints (a_cookie);
 
-    typedef map<int, IDebugger::Breakpoint> BPMap;
+    typedef map<string, IDebugger::Breakpoint> BPMap;
     BPMap &bp_cache =
         get_cached_breakpoints ();
     BPMap::iterator b_it;
@@ -4751,29 +4744,29 @@ GDBEngine::set_breakpoint_ignore_count (gint a_break_num,
 }
 
 void
-GDBEngine::set_breakpoint_condition (gint a_break_num,
+GDBEngine::set_breakpoint_condition (const string &a_break_num,
                                      const UString &a_condition,
                                      const UString &a_cookie)
 {
     LOG_FUNCTION_SCOPE_NORMAL_DD;
 
-    RETURN_IF_FAIL (a_break_num >= 0);
+    RETURN_IF_FAIL (!a_break_num.empty ());
 
     Command command ("set-breakpoint-condition",
-                     "-break-condition " + UString::from_int (a_break_num)
+                     "-break-condition " + a_break_num
                      + " " + a_condition, a_cookie);
     queue_command (command);
     list_breakpoints (a_cookie);
 }
 
 void
-GDBEngine::enable_countpoint (gint a_break_num,
+GDBEngine::enable_countpoint (const string &a_break_num,
                              bool a_yes,
                              const UString &a_cookie)
 {
     LOG_FUNCTION_SCOPE_NORMAL_DD;
 
-    typedef map<int, IDebugger::Breakpoint> BPMap;
+    typedef map<string, IDebugger::Breakpoint> BPMap;
     BPMap &bp_cache = get_cached_breakpoints ();
     BPMap::const_iterator nil = bp_cache.end ();
 
@@ -4791,12 +4784,12 @@ GDBEngine::enable_countpoint (gint a_break_num,
         command_name = "disable-countpoint";
     }
     Command command (command_name, command_str.str (), a_cookie);
-    command.tag2 (a_break_num);
+    command.tag0 (a_break_num);
     queue_command (command);
 }
 
 bool
-GDBEngine::is_countpoint (gint a_bp_num) const
+GDBEngine::is_countpoint (const string &a_bp_num) const
 {
     Breakpoint bp;
     if (get_breakpoint_from_cache (a_bp_num, bp))
@@ -4878,7 +4871,7 @@ GDBEngine::list_breakpoints (const UString &a_cookie)
     queue_command (Command ("list-breakpoints", "-break-list", a_cookie));
 }
 
-map<int, IDebugger::Breakpoint>&
+map<string, IDebugger::Breakpoint>&
 GDBEngine::get_cached_breakpoints ()
 {
 
@@ -4886,10 +4879,10 @@ GDBEngine::get_cached_breakpoints ()
 }
 
 bool
-GDBEngine::get_breakpoint_from_cache (int a_num,
+GDBEngine::get_breakpoint_from_cache (const string &a_num,
                                       IDebugger::Breakpoint &a_bp) const
 {
-    typedef map<int, IDebugger::Breakpoint> BPMap;
+    typedef map<string, IDebugger::Breakpoint> BPMap;
     BPMap &bp_cache =
         const_cast<GDBEngine*> (this)->get_cached_breakpoints ();
     BPMap::const_iterator nil = bp_cache.end ();
@@ -4912,7 +4905,7 @@ GDBEngine::append_breakpoint_to_cache (IDebugger::Breakpoint &a_break)
 {
     LOG_FUNCTION_SCOPE_NORMAL_DD;
 
-    typedef map<int, IDebugger::Breakpoint> BpMap;
+    typedef map<string, IDebugger::Breakpoint> BpMap;
     typedef BpMap::iterator BpIt;
 
     BpMap &bp_cache = m_priv->cached_breakpoints;
@@ -4929,7 +4922,7 @@ GDBEngine::append_breakpoint_to_cache (IDebugger::Breakpoint &a_break)
                 << " is not a count point");
     }
     LOG_DD ("initial_ignore_count on bp "
-            << (int)  a_break.number ()
+            <<  a_break.number ()
             << ": " << a_break.initial_ignore_count ());
 
     // First, let's see if a_break is already in our cache.
@@ -4947,7 +4940,7 @@ GDBEngine::append_breakpoint_to_cache (IDebugger::Breakpoint &a_break)
         if (cur->second.initial_ignore_count () != a_break.initial_ignore_count ()) {
             a_break.initial_ignore_count (cur->second.initial_ignore_count ());
             LOG_DD ("initial_ignore_count propagated on bp "
-                    << (int)  a_break.number ()
+                    << a_break.number ()
                     << ": " << a_break.initial_ignore_count ());
         }
     } else {
@@ -4994,11 +4987,11 @@ GDBEngine::append_breakpoint_to_cache (IDebugger::Breakpoint &a_break)
 /// \param a_breaks the set of breakpoints to append to the cache.
 void
 GDBEngine::append_breakpoints_to_cache
-                            (map<int, IDebugger::Breakpoint> &a_breaks)
+                            (map<string, IDebugger::Breakpoint> &a_breaks)
 {
     LOG_FUNCTION_SCOPE_NORMAL_DD;
 
-    map<int, IDebugger::Breakpoint>::iterator iter;
+    map<string, IDebugger::Breakpoint>::iterator iter;
     for (iter = a_breaks.begin (); iter != a_breaks.end (); ++iter)
         append_breakpoint_to_cache (iter->second);
 }
@@ -5078,12 +5071,12 @@ GDBEngine::choose_function_overloads (const vector<int> &a_nums,
 }
 
 void
-GDBEngine::delete_breakpoint (gint a_break_num,
+GDBEngine::delete_breakpoint (const string &a_break_num,
                               const UString &a_cookie)
 {
     LOG_FUNCTION_SCOPE_NORMAL_DD;
     queue_command (Command ("delete-breakpoint",
-                            "-break-delete " + UString::from_int (a_break_num),
+                            "-break-delete " + a_break_num,
                             a_cookie));
 }
 
diff --git a/src/dbgengine/nmv-gdb-engine.h b/src/dbgengine/nmv-gdb-engine.h
index b348a4c..28abeaa 100644
--- a/src/dbgengine/nmv-gdb-engine.h
+++ b/src/dbgengine/nmv-gdb-engine.h
@@ -71,18 +71,18 @@ public:
 
     sigc::signal<void>& inferior_re_run_signal () const;
 
-    sigc::signal<void, const map<int, IDebugger::Breakpoint>&, const UString&>&
+    sigc::signal<void, const map<string, IDebugger::Breakpoint>&, const UString&>&
                                             breakpoints_list_signal () const;
 
     sigc::signal<void,
-                const std::map<int, IDebugger::Breakpoint>&,
+                const std::map<string, IDebugger::Breakpoint>&,
                 const UString& /*cookie*/>&
         breakpoints_set_signal () const;
 
     sigc::signal<void, const vector<OverloadsChoiceEntry>&, const UString&>&
                                     got_overloads_choice_signal () const;
 
-    sigc::signal<void, const IDebugger::Breakpoint&, int, const UString&>&
+    sigc::signal<void, const IDebugger::Breakpoint&, const string&, const UString&>&
                                         breakpoint_deleted_signal () const;
 
     sigc::signal<void, const IDebugger::Breakpoint&, int>&
@@ -97,7 +97,7 @@ public:
                 bool,
                 const IDebugger::Frame&,
                 int,
-                int,
+                const string&,
                 const UString& /*cookie*/>& stopped_signal () const;
 
     sigc::signal<void,
@@ -222,7 +222,7 @@ public:
                             bool has_frame,
                             const IDebugger::Frame &a_frame,
                             int a_thread_id,
-                            int a_breakpoint_number,
+                            const string &a_breakpoint_number,
                             const UString &a_cookie);
     void on_detached_from_target_signal ();
 
@@ -327,7 +327,7 @@ public:
 
     void append_breakpoint_to_cache (IDebugger::Breakpoint &a_break);
 
-    void append_breakpoints_to_cache (map<int, IDebugger::Breakpoint>&);
+    void append_breakpoints_to_cache (map<string, IDebugger::Breakpoint>&);
 
     void do_continue (const UString &a_cookie);
 
@@ -398,29 +398,29 @@ public:
                          gint a_ignore_count,
                          const UString &a_cookie);
 
-    void enable_breakpoint (gint a_break_num,
+    void enable_breakpoint (const string& a_break_num,
                            const BreakpointsSlot &a_slot,
                            const UString &a_cookie = "");
 
-    void enable_breakpoint (gint a_break_num,
+    void enable_breakpoint (const string& a_break_num,
                             const UString &a_cookie="");
 
-    void disable_breakpoint (gint a_break_num,
+    void disable_breakpoint (const string& a_break_num,
                              const UString &a_cookie="");
 
-    void set_breakpoint_ignore_count (gint a_break_num,
+    void set_breakpoint_ignore_count (const string& a_break_num,
                                       gint a_ignore_count,
                                       const UString &a_cookie = "");
 
-    void set_breakpoint_condition (gint a_break_num,
+    void set_breakpoint_condition (const string& a_break_num,
                                    const UString &a_condition,
                                    const UString &a_cookie = "");
 
-    void enable_countpoint (gint a_break_num,
+    void enable_countpoint (const string& a_break_num,
                            bool a_flag,
                            const UString &a_cookie = "");
 
-    bool is_countpoint (gint a_break_num) const;
+    bool is_countpoint (const string& a_break_num) const;
 
     bool is_countpoint (const Breakpoint &a_breakpoint) const;
 
@@ -434,9 +434,9 @@ public:
 
     void list_breakpoints (const UString &a_cookie);
 
-    map<int, IDebugger::Breakpoint>& get_cached_breakpoints ();
+    map<string, IDebugger::Breakpoint>& get_cached_breakpoints ();
 
-    bool get_breakpoint_from_cache (int a_num,
+    bool get_breakpoint_from_cache (const string &a_num,
                                    IDebugger::Breakpoint &a_bp) const;
 
     void set_catch (const UString &a_event,
@@ -456,7 +456,7 @@ public:
 
     unsigned int get_current_thread () const;
 
-    void delete_breakpoint (gint a_break_num,
+    void delete_breakpoint (const string &a_break_num,
                             const UString &a_cookie);
 
     void select_frame (int a_frame_id,
diff --git a/src/dbgengine/nmv-gdbmi-parser.cc b/src/dbgengine/nmv-gdbmi-parser.cc
index 085781b..29499dd 100644
--- a/src/dbgengine/nmv-gdbmi-parser.cc
+++ b/src/dbgengine/nmv-gdbmi-parser.cc
@@ -107,11 +107,7 @@ while (a_from < a_input.bytes () && isblank (a_input.c_str ()[a_from])) { \
 } \
 a_to = a_from;
 
-#define SKIP_BLANK2(a_from) \
-while (!m_priv->index_passed_end (a_from) \
-       && isblank (RAW_CHAR_AT (a_from))) {     \
-    CHECK_END2 (a_from); ++a_from; \
-}
+#define SKIP_BLANK2(a_from) m_priv->skip_blank (a_from)
 
 #define RAW_CHAR_AT(cur) m_priv->raw_char_at (cur)
 
@@ -587,6 +583,14 @@ struct GDBMIParser::Priv {
         return a_index >= end;
     }
 
+    bool skip_blank (UString::size_type &i)
+    {
+        while (!index_passed_end (i)
+               && isblank (raw_char_at (i)))
+            ++i;
+        return true;
+    }
+
     void set_input (const UString &a_input)
     {
         input = a_input;
@@ -1897,7 +1901,7 @@ fetch_gdbmi_result:
             } else if (!m_priv->input.compare (cur,
                                                strlen (PREFIX_BREAKPOINT_TABLE),
                                                PREFIX_BREAKPOINT_TABLE)) {
-                map<int, IDebugger::Breakpoint> breaks;
+                map<string, IDebugger::Breakpoint> breaks;
                 if (parse_breakpoint_table (cur, cur, breaks)) {
                     result_record.breakpoints () = breaks;
                 }
@@ -2198,23 +2202,33 @@ fetch_gdbmi_result:
 }
 
 bool
-GDBMIParser::parse_breakpoint (Glib::ustring::size_type a_from,
-                               Glib::ustring::size_type &a_to,
-                               IDebugger::Breakpoint &a_bkpt)
+GDBMIParser::parse_breakpoint_with_one_loc (Glib::ustring::size_type a_from,
+                                            Glib::ustring::size_type &a_to,
+                                            bool is_sub_breakpoint,
+                                            IDebugger::Breakpoint &a_bkpt)
 {
     LOG_FUNCTION_SCOPE_NORMAL_D (GDBMI_PARSING_DOMAIN);
 
     Glib::ustring::size_type cur = a_from;
 
-    if (RAW_INPUT.compare (cur, strlen (PREFIX_BKPT), PREFIX_BKPT)) {
+    if (m_priv->index_passed_end (cur)) {
         LOG_PARSING_ERROR2 (cur);
         return false;
     }
 
-    cur += 6;
-    if (m_priv->index_passed_end (cur)) {
-        LOG_PARSING_ERROR2 (cur);
-        return false;
+    if (!is_sub_breakpoint) {
+        if (RAW_INPUT.compare (cur, strlen (PREFIX_BKPT), PREFIX_BKPT)) {
+            LOG_PARSING_ERROR2 (cur);
+            return false;
+        }
+        cur += 6;
+    } else {
+        // We must be on the starting '{'.
+        if (RAW_CHAR_AT (cur) != '{') {
+            LOG_PARSING_ERROR2 (cur);
+            return false;
+        }
+        CHECK_END2 (++cur);
     }
 
     map<UString, UString> attrs;
@@ -2275,20 +2289,33 @@ GDBMIParser::parse_breakpoint (Glib::ustring::size_type a_from,
     // well, but it seems that a lot debug info set got shipped without
     // that property. Client code should do what they can with the
     // file property only.
-    if (   (iter = attrs.find ("number"))  == null_iter
-            || (iter = attrs.find ("type"))    == null_iter
-            || (iter = attrs.find ("disp"))    == null_iter
-            || (iter = attrs.find ("enabled")) == null_iter
+    if ((iter = attrs.find ("number"))                            == null_iter
+        || (iter = attrs.find ("enabled"))                        == null_iter
+        || (!is_sub_breakpoint && ((iter = attrs.find ("type"))   == null_iter))
+        || (!is_sub_breakpoint && ((iter = attrs.find ("disp"))   == null_iter))
+        || (!is_sub_breakpoint && ((iter = attrs.find ("times"))  == null_iter))
+
           // Non regular breakpoints like those set to catch fork
           // events can have an empty address when set.
           // || (iter = attrs.find ("addr"))    == null_iter
-            || (iter = attrs.find ("times"))   == null_iter
+        
        ) {
         LOG_PARSING_ERROR2 (cur);
         return false;
     }
 
-    a_bkpt.number (atoi (attrs["number"].c_str ()));
+    if (!is_sub_breakpoint)
+        a_bkpt.number (atoi (attrs["number"].c_str ()));
+    else {
+        UString num = attrs["number"];
+        vector<UString> parts = str_utils::split (num, ".");
+        if (parts.size () > 1)
+            num = parts[1];
+        else if (parts.size ())
+            num = parts[0];
+        a_bkpt.number (atoi (num.c_str ()));
+    }
+        
     if (attrs["enabled"] == "y") {
         a_bkpt.enabled (true);
     } else {
@@ -2355,9 +2382,57 @@ GDBMIParser::parse_breakpoint (Glib::ustring::size_type a_from,
 }
 
 bool
+GDBMIParser::parse_breakpoint (Glib::ustring::size_type a_from,
+                               Glib::ustring::size_type &a_to,
+                               IDebugger::Breakpoint &a_bkpt)
+{
+    LOG_FUNCTION_SCOPE_NORMAL_D (GDBMI_PARSING_DOMAIN);
+
+    Glib::ustring::size_type cur = a_from;
+
+    if (!parse_breakpoint_with_one_loc (cur, cur,
+                                        /*is_sub_breakpoint=*/false,
+                                        a_bkpt)) {
+        LOG_PARSING_ERROR2 (cur);
+        return false;
+    }
+
+    while (true) {
+        Glib::ustring::size_type saved_cur = cur;
+        SKIP_BLANK2 (cur);
+
+        if (!END_OF_INPUT (cur)) {
+            if (RAW_CHAR_AT (cur) != ','
+                || (++cur
+                    && SKIP_BLANK2 (cur)
+                    && !END_OF_INPUT (cur) 
+                    && RAW_CHAR_AT (cur) != '{')) {
+                ;// Get out.
+            } else {
+                // So, after the previous breakpoint, we have a new breakpoint
+                // location starting with , '{number="some number", ...
+                // Let's parse that.
+                IDebugger::Breakpoint sub_bp;
+                if (!parse_breakpoint_with_one_loc (cur, cur,
+                                                    /*is_sub_breakpoint=*/true,
+                                                    sub_bp)) {
+                    LOG_PARSING_ERROR2 (cur);
+                    return false;
+                }
+                a_bkpt.append_sub_breakpoint (sub_bp);
+                continue;
+            }
+        }
+        a_to = saved_cur;
+        break;
+    }
+    return true;
+}
+
+bool
 GDBMIParser::parse_breakpoint_table (UString::size_type a_from,
                                      UString::size_type &a_to,
-                                     map<int, IDebugger::Breakpoint> &a_breakpoints)
+                                     map<string, IDebugger::Breakpoint> &a_breakpoints)
 {
     LOG_FUNCTION_SCOPE_NORMAL_D (GDBMI_PARSING_DOMAIN);
     UString::size_type cur=a_from;
@@ -2385,7 +2460,7 @@ GDBMIParser::parse_breakpoint_table (UString::size_type a_from,
         return false;
     }
 
-    map<int, IDebugger::Breakpoint> breakpoint_table;
+    map<string, IDebugger::Breakpoint> breakpoint_table;
     if (RAW_CHAR_AT (cur) == ']') {
         //there are zero breakpoints ...
     } else if (!RAW_INPUT.compare (cur, strlen (PREFIX_BKPT),
diff --git a/src/dbgengine/nmv-gdbmi-parser.h b/src/dbgengine/nmv-gdbmi-parser.h
index 10160e7..f0e6cc1 100644
--- a/src/dbgengine/nmv-gdbmi-parser.h
+++ b/src/dbgengine/nmv-gdbmi-parser.h
@@ -507,6 +507,11 @@ public:
                                    UString::size_type &a_to,
                                    Output::OutOfBandRecord &a_record);
 
+    bool parse_breakpoint_with_one_loc (Glib::ustring::size_type a_from,
+                                        Glib::ustring::size_type &a_to,
+                                        bool is_sub_breakpoint,
+                                        IDebugger::Breakpoint &a_bkpt);
+
     /// \brief parses a breakpoint definition as returned by gdb.
     ///
     ///breakpoint definition string looks like this:
@@ -526,7 +531,7 @@ public:
 
     bool parse_breakpoint_table (UString::size_type a_from,
                                  UString::size_type &a_to,
-                                 map<int, IDebugger::Breakpoint> &a_breakpoints);
+                                 map<string, IDebugger::Breakpoint> &a_breakpoints);
 
     /// parses the result of the gdbmi command
     /// "-thread-list-ids".
diff --git a/src/dbgengine/nmv-i-debugger.h b/src/dbgengine/nmv-i-debugger.h
index 26a5d1c..12c15a1 100644
--- a/src/dbgengine/nmv-i-debugger.h
+++ b/src/dbgengine/nmv-i-debugger.h
@@ -38,6 +38,7 @@
 #include "common/nmv-address.h"
 #include "common/nmv-asm-instr.h"
 #include "common/nmv-loc.h"
+#include "common/nmv-str-utils.h"
 #include "nmv-i-conf-mgr.h"
 
 using nemiver::common::SafePtr;
@@ -115,6 +116,19 @@ public:
         int m_ignore_count;
         bool m_is_read_watchpoint;
         bool m_is_write_watchpoint;
+        // The list of sub-breakpoints, in case this breakpoint is a
+        // multiple breakpoint.  In that case, each sub-breakpoint
+        // will be set to a real location of an overload function.
+        // Each sub-breakpoint will then have a non-nil
+        // m_parent_breakpoint pointer that points back to this
+        // instance, and an empty m_sub_breakpoints member.
+        vector<Breakpoint> m_sub_breakpoints;
+        // If this instance is a sub-breakpoint, i.e, a breakpoint to
+        // an overloaded function that has been set by name to all the
+        // overloads at the same time, then this is set to the id of
+        // the parent breakpoint.  The parent breakpoint contains
+        // information that are relevant for all the sub-breakpoints.
+        int m_parent_breakpoint_number;
 
     public:
         Breakpoint () {clear ();}
@@ -122,8 +136,22 @@ public:
         /// \name accessors
 
         /// @{
-        int number () const {return m_number;}
+        string number () const
+        {
+            if (is_sub_breakpoint ())
+                return (str_utils::int_to_string (parent_breakpoint_number ()) + "."
+                        + str_utils::int_to_string (sub_breakpoint_number ()));
+            else
+                return str_utils::int_to_string (sub_breakpoint_number ());
+        }
+
+        void number (string& s) const
+        {
+            s = number ();
+        }
+
         void number (int a_in) {m_number = a_in;}
+        int sub_breakpoint_number () const {return m_number;}
 
         bool enabled () const {return m_enabled;}
         void enabled (bool a_in) {m_enabled = a_in;}
@@ -180,6 +208,29 @@ public:
             return false;
         }
 
+        /// Test whether this breakpoint has multiple location.
+        ///
+        /// Each location is then represented by a sub-breakpoint,
+        /// that is a child breakpoint of this instance of
+        /// breakpoint.  The sub-breakpoints can be retrieved by the
+        /// #sub_breakpoints below.
+        bool has_multiple_locations () const {return !m_sub_breakpoints.empty ();}
+
+        void append_sub_breakpoint (Breakpoint& b)
+        {
+            b.m_parent_breakpoint_number = m_number;
+            m_sub_breakpoints.push_back (b);
+        }
+
+        const vector<Breakpoint>& sub_breakpoints () const
+        {
+            return m_sub_breakpoints;
+        }
+
+        int parent_breakpoint_number () const {return m_parent_breakpoint_number;}
+
+        bool is_sub_breakpoint () const {return !!parent_breakpoint_number ();}
+
         Type type () const {return m_type;}
         void type (Type a_type) {m_type = a_type;}
 
@@ -202,6 +253,8 @@ public:
             m_ignore_count = 0;
             m_is_read_watchpoint = false;
             m_is_write_watchpoint = false;
+            m_sub_breakpoints.clear ();
+            m_parent_breakpoint_number = 0;
         }
     };//end class Breakpoint
 
@@ -1000,7 +1053,7 @@ public:
         BreakpointSlot;
 
     typedef sigc::slot<void,
-                       const std::map<int, IDebugger::Breakpoint>&>
+                       const std::map<string, IDebugger::Breakpoint>&>
         BreakpointsSlot;
 
     typedef sigc::slot<void, Loc&> LocSlot;
@@ -1038,7 +1091,7 @@ public:
 
     virtual sigc::signal<void,
                         const IDebugger::Breakpoint&,
-                        int /*breakpoint command*/,
+                        const string& /*breakpoint number*/,
                         const UString & /*cookie*/>&
                                      breakpoint_deleted_signal () const=0;
 
@@ -1048,12 +1101,12 @@ public:
     /// IDebugger does not cache the list of breakpoints. This must
     /// be fixed at some point.
     virtual sigc::signal<void,
-                         const map<int, IDebugger::Breakpoint>&,
+                         const map<string, IDebugger::Breakpoint>&,
                          const UString& /*cookie*/>&
                                          breakpoints_list_signal () const=0;
 
     virtual sigc::signal<void,
-                        const std::map<int, IDebugger::Breakpoint>&,
+                        const std::map<string, IDebugger::Breakpoint>&,
                         const UString& /*cookie*/>&
                         breakpoints_set_signal () const = 0;
 
@@ -1067,9 +1120,9 @@ public:
                          bool /*has frame*/,
                          const IDebugger::Frame&/*the frame*/,
                          int /*thread id*/,
-                         int /*breakpoint number,
-                               meaningfull only when
-                               reason == IDebugger::BREAKPOINT_HIT*/,
+                         const string& /*breakpoint number,
+                                         meaningfull only when
+                                         reason == IDebugger::BREAKPOINT_HIT*/,
                          const UString& /*cookie*/>& stopped_signal () const=0;
 
     virtual sigc::signal<void,
@@ -1364,30 +1417,30 @@ public:
                                  gint a_ignore_count = 0,
                                  const UString &a_cookie = "") = 0;
 
-    virtual void enable_breakpoint (gint a_break_num,
+    virtual void enable_breakpoint (const string& a_break_num,
                                     const BreakpointsSlot &a_slot,
                                     const UString &a_cookie="") = 0;
 
-    virtual void enable_breakpoint (gint a_break_num,
+    virtual void enable_breakpoint (const string& a_break_num,
                                     const UString &a_cookie="") = 0;
 
-    virtual void disable_breakpoint (gint a_break_num,
+    virtual void disable_breakpoint (const string& a_break_num,
                                      const UString &a_cookie="") = 0;
 
     virtual void set_breakpoint_ignore_count
-                                        (gint a_break_num,
+                                        (const string& a_break_num,
                                          gint a_ignore_count,
                                          const UString &a_cookie = "") = 0;
 
-    virtual void set_breakpoint_condition (gint a_break_num,
+    virtual void set_breakpoint_condition (const string& a_break_num,
                                            const UString &a_condition,
                                            const UString &a_cookie = "") = 0;
 
-    virtual void enable_countpoint (gint a_break_num,
+    virtual void enable_countpoint (const string& a_break_num,
                                     bool a_flag,
                                     const UString &a_cookie ="") = 0;
 
-    virtual bool is_countpoint (gint a_break_num) const = 0;
+    virtual bool is_countpoint (const string &a_break_num) const = 0;
 
     virtual bool is_countpoint (const Breakpoint &a_breakpoint) const = 0;
 
@@ -1405,9 +1458,9 @@ public:
 
     virtual void list_breakpoints (const UString &a_cookie="") = 0;
 
-    virtual const map<int, Breakpoint>& get_cached_breakpoints () = 0;
+    virtual const map<string, Breakpoint>& get_cached_breakpoints () = 0;
 
-    virtual bool get_breakpoint_from_cache (int a_num,
+    virtual bool get_breakpoint_from_cache (const string &a_num,
                                             IDebugger::Breakpoint &a_bp)
         const = 0;
 
@@ -1417,7 +1470,7 @@ public:
     virtual void choose_function_overloads (const vector<int> &a_numbers,
                                             const UString &a_cookie="") = 0;
 
-    virtual void delete_breakpoint (gint a_break_num,
+    virtual void delete_breakpoint (const string &a_break_num,
                                     const UString &a_cookie="") = 0;
 
     virtual void list_threads (const UString &a_cookie="") = 0;
diff --git a/src/persp/dbgperspective/nmv-breakpoints-view.cc 
b/src/persp/dbgperspective/nmv-breakpoints-view.cc
index e9e3239..6137555 100644
--- a/src/persp/dbgperspective/nmv-breakpoints-view.cc
+++ b/src/persp/dbgperspective/nmv-breakpoints-view.cc
@@ -38,7 +38,7 @@
 namespace nemiver {
 
 struct BPColumns : public Gtk::TreeModelColumnRecord {
-    Gtk::TreeModelColumn<int> id;
+    Gtk::TreeModelColumn<Glib::ustring> id;
     Gtk::TreeModelColumn<bool> enabled;
     Gtk::TreeModelColumn<Glib::ustring> address;
     Gtk::TreeModelColumn<Glib::ustring> filename;
@@ -231,8 +231,39 @@ public:
         return is_visible;
     }
 
+    /// If a_bp is a breakpoint already present in the tree model,
+    /// then update it.  Otherwise, add it.
     void
-    set_breakpoints (const std::map<int, IDebugger::Breakpoint> &a_breakpoints)
+    update_or_append_breakpoint (const IDebugger::Breakpoint &a_bp)
+    {
+        Gtk::TreeModel::iterator i = find_breakpoint_in_model (a_bp);
+        if (i) {
+            LOG_DD ("Updating breakpoint " << a_bp.number ());
+            update_breakpoint (i, a_bp);
+        } else {
+            // Normally, we shouldn't reach this place, as we
+            // should have been notified about any new
+            // breakpoint by mean of
+            // IDebugger::breakpoint_set_signal, and
+            // on_debugger_breakpoint_set_signal should have
+            // added the breakpoint to the model.  It turned
+            // out we can reach this point nevertheless, when,
+            // say, a breakpoint is added by mean of a GDB
+            // script. In that case, the GDB implementation of
+            // IDebugger doesn't get any GDB/MI notification
+            // upon breakpoint creation, so we don't get the
+            // IDebugger::breakpoint_set_signal notification.
+            // Let's just add the breakpoint now then.
+            LOG_DD ("Didn't find breakpoint: "
+                    << a_bp.number ()
+                    << " so going to add it");
+            append_breakpoint (a_bp);
+        }
+    }
+
+    /// Set the breakpoints to our tree model.
+    void
+    set_breakpoints (const std::map<string, IDebugger::Breakpoint> &a_breakpoints)
     {
         if (a_breakpoints.empty ()) {
             return;
@@ -243,45 +274,30 @@ public:
             // searching for things to update, just add them all directly
             add_breakpoints (a_breakpoints);
         } else {
-            //find breakpoints that need adding or updating
-            std::map<int, IDebugger::Breakpoint>::const_iterator breakmap_iter;
-            for (breakmap_iter = a_breakpoints.begin ();
-                 breakmap_iter != a_breakpoints.end ();
-                 ++breakmap_iter) {
-                Gtk::TreeModel::iterator tree_iter =
-                    find_breakpoint_in_model (breakmap_iter->second);
-                if (tree_iter) {
-                    LOG_DD ("Updating breakpoint "
-                            << breakmap_iter->second.number ());
-                    update_breakpoint (tree_iter, breakmap_iter->second);
+            // find breakpoints that need adding or updating
+            std::map<string, IDebugger::Breakpoint>::const_iterator bi;
+            for (bi = a_breakpoints.begin ();
+                 bi != a_breakpoints.end ();
+                 ++bi) {
+                if (bi->second.has_multiple_locations ()) {
+                    vector<IDebugger::Breakpoint>::const_iterator si;
+                    for (si = bi->second.sub_breakpoints ().begin ();
+                         si != bi->second.sub_breakpoints ().end ();
+                         ++si)
+                        update_or_append_breakpoint (*si);
                 } else {
-                    // Normally, we shouldn't reach this place, as we
-                    // should have been notified about any new
-                    // breakpoint by mean of
-                    // IDebugger::breakpoint_set_signal, and
-                    // on_debugger_breakpoint_set_signal should have
-                    // added the breakpoint to the model.  It turned
-                    // out we can reach this point nevertheless, when,
-                    // say, a breakpoint is added by mean of a GDB
-                    // script. In that case, the GDB implementation of
-                    // IDebugger doesn't get any GDB/MI notification
-                    // upon breakpoint creation, so we don't get the
-                    // IDebugger::breakpoint_set_signal notification.
-                    // Let's just add the breakpoint now then.
-                    LOG_DD ("Didn't find breakpoint: " << breakmap_iter->first
-                            << " so going to add it");
-                    append_breakpoint (breakmap_iter->second);
+                    update_or_append_breakpoint (bi->second);
                 }
             }
         }
     }
 
     void
-    add_breakpoints (const std::map<int, IDebugger::Breakpoint> &a_breakpoints)
+    add_breakpoints (const std::map<string, IDebugger::Breakpoint> &a_breakpoints)
     {
         THROW_IF_FAIL (list_store);
 
-        std::map<int, IDebugger::Breakpoint>::const_iterator break_iter;
+        std::map<string, IDebugger::Breakpoint>::const_iterator break_iter;
         for (break_iter = a_breakpoints.begin ();
                 break_iter != a_breakpoints.end ();
                 ++break_iter) {
@@ -291,10 +307,10 @@ public:
 
     bool
     breakpoint_list_has_id
-        (const std::map<int, IDebugger::Breakpoint> &a_breakpoints,
-         int a_id)
+        (const std::map<string, IDebugger::Breakpoint> &a_breakpoints,
+         const string &a_id)
     {
-        std::map<int, IDebugger::Breakpoint>::const_iterator breakmap_iter;
+        std::map<string, IDebugger::Breakpoint>::const_iterator breakmap_iter;
         for (breakmap_iter = a_breakpoints.begin ();
                 breakmap_iter != a_breakpoints.end (); ++ breakmap_iter) {
             if (a_id == breakmap_iter->second.number ()) {
@@ -360,13 +376,20 @@ public:
         (*a_iter)[get_bp_cols ().hits] = a_breakpoint.nb_times_hit ();
     }
 
-    Gtk::TreeModel::iterator 
-    append_breakpoint (const IDebugger::Breakpoint &a_breakpoint)
+    void
+    append_breakpoint (const IDebugger::Breakpoint &a_bp)
     {
-        Gtk::TreeModel::iterator tree_iter = list_store->append ();
-        update_breakpoint (tree_iter, a_breakpoint);
-
-        return tree_iter;
+        if (a_bp.has_multiple_locations ()) {
+            vector<IDebugger::Breakpoint>::const_iterator bi;
+            for (bi = a_bp.sub_breakpoints ().begin ();
+                 bi != a_bp.sub_breakpoints ().end ();
+                 ++bi) {
+                append_breakpoint (*bi);
+            }
+        } else {
+            Gtk::TreeModel::iterator tree_iter = list_store->append ();
+            update_breakpoint (tree_iter, a_bp);
+        }
     }
 
     void
@@ -458,10 +481,10 @@ public:
     }
 
     void
-    erase_breakpoint (int a_bp_num)
+    erase_breakpoint (const string &a_bp_num)
     {
 
-        LOG_DD ("asked to erase bp num:" << (int) a_bp_num);
+        LOG_DD ("asked to erase bp num:" << a_bp_num);
 
         Gtk::TreeModel::iterator iter;
         for (iter = list_store->children ().begin ();
@@ -480,7 +503,7 @@ public:
 
     void 
     on_debugger_breakpoints_list_signal
-                            (const map<int, IDebugger::Breakpoint> &a_breaks,
+                            (const map<string, IDebugger::Breakpoint> &a_breaks,
                              const UString &a_cookie)
     {
         NEMIVER_TRY
@@ -494,7 +517,7 @@ public:
                                 bool /*a_has_frame*/,
                                 const IDebugger::Frame &/*a_frame*/,
                                 int /*a_thread_id*/,
-                                int a_bkpt_num,
+                                const string &a_bkpt_num,
                                 const UString &/*a_cookie*/)
     {
         LOG_FUNCTION_SCOPE_NORMAL_DD;
@@ -513,7 +536,7 @@ public:
                 is_up2date = false;
             }
         } else if (a_reason == IDebugger::WATCHPOINT_SCOPE) {
-            LOG_DD ("erase watchpoint num: " << (int) a_bkpt_num);
+            LOG_DD ("erase watchpoint num: " << a_bkpt_num);
             erase_breakpoint (a_bkpt_num);
         }
 
@@ -521,11 +544,10 @@ public:
     }
 
     void
-    on_debugger_breakpoint_deleted_signal (const IDebugger::Breakpoint &a_break,
-                                           int a_break_number,
-                                           const UString &a_cookie)
+    on_debugger_breakpoint_deleted_signal (const IDebugger::Breakpoint &/*a_break*/,
+                                           const string &a_break_number,
+                                           const UString &/*a_cookie*/)
     {
-        if (a_break.number () || a_cookie.empty()) {}
         NEMIVER_TRY
         list<Gtk::TreeModel::iterator> iters_to_erase;
         for (Gtk::TreeModel::iterator iter = list_store->children ().begin ();
@@ -547,12 +569,12 @@ public:
 
     void
     on_debugger_breakpoints_set_signal
-    (const std::map<int, IDebugger::Breakpoint> &a,
+    (const std::map<string, IDebugger::Breakpoint> &a,
      const UString &)
     {
         NEMIVER_TRY;
 
-        std::map<int, IDebugger::Breakpoint>::const_iterator i;
+        std::map<string, IDebugger::Breakpoint>::const_iterator i;
         for (i = a.begin (); i != a.end (); ++i) {
             LOG_DD ("Adding breakpoints "
                     << i->second.number ());
@@ -663,8 +685,8 @@ public:
         for (it=paths.begin (); it != paths.end (); ++it) {
             tree_iter = list_store->get_iter (*it);
             if (tree_iter) {
-                debugger->delete_breakpoint
-                                ((*tree_iter)[get_bp_cols ().id]);
+                Glib::ustring bp_id = (*tree_iter)[get_bp_cols ().id];
+                debugger->delete_breakpoint (bp_id);
             }
         }
     }
@@ -694,22 +716,21 @@ public:
     void
     on_breakpoint_enable_toggled (const Glib::ustring& path)
     {
-        NEMIVER_TRY
+        NEMIVER_TRY;
 
         THROW_IF_FAIL (tree_view);
         Gtk::TreeModel::iterator tree_iter =
                                     tree_view->get_model ()->get_iter (path);
         if (tree_iter) {
+            Glib::ustring bp_id = (*tree_iter)[get_bp_cols ().id];
             if ((*tree_iter)[get_bp_cols ().enabled]) {
-                debugger->enable_breakpoint
-                                    ((*tree_iter)[get_bp_cols ().id]);
+                debugger->enable_breakpoint (bp_id);
             } else {
-                debugger->disable_breakpoint
-                                    ((*tree_iter)[get_bp_cols ().id]);
+                debugger->disable_breakpoint (bp_id);
             }
         }
 
-        NEMIVER_CATCH
+        NEMIVER_CATCH;
     }
 
     void
@@ -722,12 +743,11 @@ public:
             tree_view->get_model ()->get_iter (path);
         
         if (tree_iter) {
+            Glib::ustring bp_id = (*tree_iter)[get_bp_cols ().id];
             if ((*tree_iter)[get_bp_cols ().is_countpoint]) {
-                debugger->enable_countpoint
-                    ((*tree_iter)[get_bp_cols ().id], true);
+                debugger->enable_countpoint (bp_id, true);
             } else {
-                debugger->enable_countpoint
-                    ((*tree_iter)[get_bp_cols ().id], false);
+                debugger->enable_countpoint (bp_id, false);
             }
         }
         NEMIVER_CATCH;
@@ -756,8 +776,8 @@ public:
 
         if (is_standard_bp) {
             int count = atoi (a_text.raw ().c_str ());
-            debugger->set_breakpoint_ignore_count ((*it)[get_bp_cols ().id],
-                                                   count);
+            Glib::ustring bp_id = (*it)[get_bp_cols ().id];
+            debugger->set_breakpoint_ignore_count (bp_id, count);
         }
         NEMIVER_CATCH
     }
@@ -776,9 +796,10 @@ public:
             ? true
             : false;
 
-        if (is_standard_bp)
-            debugger->set_breakpoint_condition ((*it)[get_bp_cols ().id],
-                                                a_text);
+        if (is_standard_bp) {
+            Glib::ustring bp_id = (*it)[get_bp_cols ().id];
+            debugger->set_breakpoint_condition (bp_id, a_text);
+        }
 
         NEMIVER_CATCH
     }
@@ -808,7 +829,7 @@ BreakpointsView::widget () const
 
 void
 BreakpointsView::set_breakpoints
-                (const std::map<int, IDebugger::Breakpoint> &a_breakpoints)
+                (const std::map<string, IDebugger::Breakpoint> &a_breakpoints)
 {
     THROW_IF_FAIL (m_priv);
     m_priv->set_breakpoints (a_breakpoints);
diff --git a/src/persp/dbgperspective/nmv-breakpoints-view.h b/src/persp/dbgperspective/nmv-breakpoints-view.h
index 7f47763..4e58682 100644
--- a/src/persp/dbgperspective/nmv-breakpoints-view.h
+++ b/src/persp/dbgperspective/nmv-breakpoints-view.h
@@ -56,7 +56,7 @@ public:
     virtual ~BreakpointsView ();
     Gtk::Widget& widget () const;
     void set_breakpoints
-                (const std::map<int, IDebugger::Breakpoint> &a_breakpoints);
+                (const std::map<string, IDebugger::Breakpoint> &a_breakpoints);
     void clear ();
     void re_init ();
     sigc::signal<void,
diff --git a/src/persp/dbgperspective/nmv-call-stack.cc b/src/persp/dbgperspective/nmv-call-stack.cc
index d765fd4..68b80d1 100644
--- a/src/persp/dbgperspective/nmv-call-stack.cc
+++ b/src/persp/dbgperspective/nmv-call-stack.cc
@@ -297,7 +297,7 @@ struct CallStack::Priv {
                                 bool /*a_has_frame*/,
                                 const IDebugger::Frame &/*a_frame*/,
                                 int /*a_thread_id*/,
-                                int /*a_bp_num*/,
+                                const string& /*a_bp_num*/,
                                 const UString &a_cookie)
     {
         LOG_FUNCTION_SCOPE_NORMAL_DD;
diff --git a/src/persp/dbgperspective/nmv-dbg-perspective.cc b/src/persp/dbgperspective/nmv-dbg-perspective.cc
index e5daebe..a00311d 100644
--- a/src/persp/dbgperspective/nmv-dbg-perspective.cc
+++ b/src/persp/dbgperspective/nmv-dbg-perspective.cc
@@ -274,7 +274,7 @@ private:
     void on_jump_to_location_action ();
     void on_jump_to_current_location_action ();
     void on_jump_and_break_to_current_location_action ();
-    void on_break_before_jump (const std::map<int,
+    void on_break_before_jump (const std::map<string,
                                               IDebugger::Breakpoint>&,
                                const Loc &a_loc);
     void on_set_breakpoint_action ();
@@ -349,15 +349,15 @@ private:
                                           const UString &a_cookie);
 
     void on_debugger_breakpoints_set_signal
-    (const std::map<int, IDebugger::Breakpoint>&, const UString&);
+    (const std::map<string, IDebugger::Breakpoint>&, const UString&);
 
     void on_debugger_breakpoints_list_signal
-                                (const map<int, IDebugger::Breakpoint> &,
+                                (const map<string, IDebugger::Breakpoint> &,
                                  const UString &a_cookie);
 
     void on_debugger_breakpoint_deleted_signal
                                         (const IDebugger::Breakpoint&,
-                                         int,
+                                         const string&,
                                          const UString &a_cookie);
 
     void on_debugger_got_overloads_choice_signal
@@ -368,7 +368,7 @@ private:
                                      bool a_has_frame,
                                      const IDebugger::Frame &,
                                      int a_thread_id,
-                                     int,
+                                     const string&,
                                      const UString&);
     void on_program_finished_signal ();
     void on_engine_died_signal ();
@@ -630,7 +630,7 @@ public:
     void do_jump_to_current_location ();
     void do_jump_and_break_to_location (const Loc&);
     void do_jump_and_break_to_current_location ();
-    void jump_to_location (const map<int, IDebugger::Breakpoint>&,
+    void jump_to_location (const map<string, IDebugger::Breakpoint>&,
                            const Loc &);
     void jump_to_location_from_dialog (const SetJumpToDialog &);
     void set_breakpoint_at_current_line_using_dialog ();
@@ -648,7 +648,7 @@ public:
     void re_initialize_set_breakpoints ();
     void append_breakpoint (const IDebugger::Breakpoint &a_breakpoint);
     void append_breakpoints
-                    (const map<int, IDebugger::Breakpoint> &a_breaks);
+                    (const map<string, IDebugger::Breakpoint> &a_breaks);
 
     const IDebugger::Breakpoint* get_breakpoint (const Loc&) const;
     const IDebugger::Breakpoint* get_breakpoint (const UString &a_file_name,
@@ -656,7 +656,7 @@ public:
     const IDebugger::Breakpoint* get_breakpoint (const Address &) const;
 
     bool delete_breakpoint ();
-    bool delete_breakpoint (int a_breakpoint_num);
+    bool delete_breakpoint (const string &a_breakpoint_num);
     bool delete_breakpoint (const UString &a_file_path,
                             int a_linenum);
     bool delete_breakpoint (const Address &a_address);
@@ -699,7 +699,8 @@ public:
     void toggle_breakpoint_enabled (const UString &a_file_path,
                                     int a_linenum);
     void toggle_breakpoint_enabled (const Address &a);
-    void toggle_breakpoint_enabled (int a_break_num, bool a_enabled);
+    void toggle_breakpoint_enabled (const string &a_break_num,
+                                    bool a_enabled);
     void toggle_breakpoint_enabled ();
 
     void update_src_dependant_bp_actions_sensitiveness ();
@@ -716,8 +717,8 @@ public:
                                    bool is_countpoint,
                                    bool enabled);
     void delete_visual_breakpoint (const UString &a_file_name, int a_linenum);
-    void delete_visual_breakpoint (map<int, IDebugger::Breakpoint>::iterator &a_i);
-    void delete_visual_breakpoint (int a_breaknum);
+    void delete_visual_breakpoint (map<string, IDebugger::Breakpoint>::iterator &a_i);
+    void delete_visual_breakpoint (const string &a_breaknum);
     void delete_visual_breakpoints ();
     void choose_function_overload
                 (const vector<IDebugger::OverloadsChoiceEntry> &a_entries);
@@ -934,7 +935,7 @@ struct DBGPerspective::Priv {
     IDebuggerSafePtr debugger;
     IDebugger::Frame current_frame;
     int current_thread_id;
-    map<int, IDebugger::Breakpoint> breakpoints;
+    map<string, IDebugger::Breakpoint> breakpoints;
     ISessMgrSafePtr session_manager;
     ISessMgr::Session session;
     IProcMgrSafePtr process_manager;
@@ -1563,7 +1564,7 @@ DBGPerspective::on_jump_and_break_to_current_location_action ()
 /// callback.
 void
 DBGPerspective::on_break_before_jump
-(const std::map<int, IDebugger::Breakpoint> &,
+(const std::map<string, IDebugger::Breakpoint> &,
  const Loc &a_loc)
 {
     LOG_FUNCTION_SCOPE_NORMAL_DD;
@@ -2372,7 +2373,7 @@ DBGPerspective::on_debugger_command_done_signal (const UString &a_command,
 ///
 void
 DBGPerspective::on_debugger_breakpoints_set_signal
-(const std::map<int, IDebugger::Breakpoint> &a,
+(const std::map<string, IDebugger::Breakpoint> &a,
  const UString&)
 {
     append_breakpoints (a);
@@ -2380,7 +2381,7 @@ DBGPerspective::on_debugger_breakpoints_set_signal
 
 void
 DBGPerspective::on_debugger_breakpoints_list_signal
-                            (const map<int, IDebugger::Breakpoint> &a_breaks,
+                            (const map<string, IDebugger::Breakpoint> &a_breaks,
                              const UString &a_cookie)
 {
     LOG_FUNCTION_SCOPE_NORMAL_DD;
@@ -2399,7 +2400,7 @@ DBGPerspective::on_debugger_breakpoints_list_signal
         int line = atoi
                 (a_cookie.substr (start_of_line,
                                   a_cookie.size () - start_of_line).c_str ());
-        map<int, IDebugger::Breakpoint>::const_iterator break_iter;
+        map<string, IDebugger::Breakpoint>::const_iterator break_iter;
         for (break_iter = a_breaks.begin ();
              break_iter != a_breaks.end ();
              ++break_iter) {
@@ -2425,7 +2426,9 @@ void
 DBGPerspective::on_debugger_stopped_signal (IDebugger::StopReason a_reason,
                                             bool /*a_has_frame*/,
                                             const IDebugger::Frame &a_frame,
-                                            int a_thread_id, int, const UString &)
+                                            int a_thread_id,
+                                            const string &,
+                                            const UString &)
 {
     LOG_FUNCTION_SCOPE_NORMAL_DD;
 
@@ -2528,7 +2531,7 @@ DBGPerspective::on_frame_selected_signal (int /* a_index */,
 void
 DBGPerspective::on_debugger_breakpoint_deleted_signal
                                         (const IDebugger::Breakpoint &,
-                                         int a_break_number,
+                                         const string &a_break_number,
                                          const UString &)
 {
     LOG_FUNCTION_SCOPE_NORMAL_DD;
@@ -4186,7 +4189,7 @@ DBGPerspective::get_frame_breakpoints_address_range
 
     Range range = a_range;
     bool result = false;
-    map<int, IDebugger::Breakpoint>::const_iterator it;
+    map<string, IDebugger::Breakpoint>::const_iterator it;
     for (it = m_priv->breakpoints.begin ();
          it != m_priv->breakpoints.end ();
          ++it) {
@@ -5144,7 +5147,7 @@ DBGPerspective::record_and_save_session (ISessMgr::Session &a_session)
     // Record regular breakpoints and watchpoints in the session
     a_session.breakpoints ().clear ();
     a_session.watchpoints ().clear ();
-    map<int, IDebugger::Breakpoint>::const_iterator break_iter;
+    map<string, IDebugger::Breakpoint>::const_iterator break_iter;
     for (break_iter = m_priv->breakpoints.begin ();
          break_iter != m_priv->breakpoints.end ();
          ++break_iter) {
@@ -6124,10 +6127,10 @@ DBGPerspective::execute_program
     LOG_DD ("is new prog: " << is_new_program);
 
     // Save the current breakpoints aside.
-    map<int, IDebugger::Breakpoint> saved_bps = m_priv->breakpoints;
+    map<string, IDebugger::Breakpoint> saved_bps = m_priv->breakpoints;
 
     // delete old breakpoints, if any.
-    map<int, IDebugger::Breakpoint>::const_iterator bp_it;
+    map<string, IDebugger::Breakpoint>::const_iterator bp_it;
     for (bp_it = saved_bps.begin ();
          bp_it != saved_bps.end ();
          ++bp_it) {
@@ -6168,7 +6171,7 @@ DBGPerspective::execute_program
     // set a breakpoint in 'main' by default.
     if (a_breaks.empty ()) {
         if (!is_new_program) {
-            map<int, IDebugger::Breakpoint>::const_iterator it;
+            map<string, IDebugger::Breakpoint>::const_iterator it;
             for (it = saved_bps.begin ();
                  it != saved_bps.end ();
                  ++it) {
@@ -6717,7 +6720,7 @@ DBGPerspective::do_jump_and_break_to_current_location ()
 ///
 /// \param a_loc the location to jump to.
 void
-DBGPerspective::jump_to_location (const map<int, IDebugger::Breakpoint>&,
+DBGPerspective::jump_to_location (const map<string, IDebugger::Breakpoint>&,
                                   const Loc &a_loc)
 {
     debugger ()->jump_to_position (a_loc, &null_default_slot);
@@ -6849,7 +6852,7 @@ DBGPerspective::re_initialize_set_breakpoints ()
 {
     LOG_FUNCTION_SCOPE_NORMAL_DD;
 
-    typedef map<int, IDebugger::Breakpoint> BPMap;
+    typedef map<string, IDebugger::Breakpoint> BPMap;
     BPMap &bps = m_priv->breakpoints;
 
     // Re-set ignore count on set breakpoints.
@@ -6881,7 +6884,6 @@ DBGPerspective::append_breakpoint (const IDebugger::Breakpoint &a_breakpoint)
     m_priv->breakpoints[a_breakpoint.number ()] = a_breakpoint;
     m_priv->breakpoints[a_breakpoint.number ()].file_full_name (file_path);
 
-
     if (// We don't know how to graphically represent non-standard
         // breakpoints (e.g watchpoints) at this moment, so let's not
         // bother trying to graphically represent them.
@@ -6914,7 +6916,7 @@ DBGPerspective::append_breakpoint (const IDebugger::Breakpoint &a_breakpoint)
             case SourceEditor::BUFFER_TYPE_UNDEFINED:
                 break;
         }
-    } else {
+    } else if (!a_breakpoint.has_multiple_locations ()) {
         // We not could find an editor for the file of the breakpoint.
         // Ask the backend for asm instructions and set the visual breakpoint
         // at the breakpoint address.
@@ -6937,15 +6939,23 @@ DBGPerspective::append_breakpoint (const IDebugger::Breakpoint &a_breakpoint)
                         a_breakpoint);
         disassemble_around_address_and_do (addr, set_bp);
     }
+
+    if (a_breakpoint.has_multiple_locations ()) {
+        vector<IDebugger::Breakpoint>::const_iterator i;
+        for (i = a_breakpoint.sub_breakpoints ().begin ();
+             i != a_breakpoint.sub_breakpoints ().end ();
+             ++i)
+            append_breakpoint (*i);
+    }
 }
 
 void
 DBGPerspective::append_breakpoints
-                        (const map<int, IDebugger::Breakpoint> &a_breaks)
+                        (const map<string, IDebugger::Breakpoint> &a_breaks)
 {
     LOG_FUNCTION_SCOPE_NORMAL_DD;
 
-    map<int, IDebugger::Breakpoint>::const_iterator iter;
+    map<string, IDebugger::Breakpoint>::const_iterator iter;
     for (iter = a_breaks.begin (); iter != a_breaks.end (); ++iter)
         append_breakpoint (iter->second);
 }
@@ -6992,7 +7002,7 @@ DBGPerspective::get_breakpoint (const UString &a_file_name,
 
     UString breakpoint = a_file_name + ":" + UString::from_int (a_line_num);
 
-    map<int, IDebugger::Breakpoint>::const_iterator iter;
+    map<string, IDebugger::Breakpoint>::const_iterator iter;
     for (iter = m_priv->breakpoints.begin ();
          iter != m_priv->breakpoints.end ();
          ++iter) {
@@ -7017,7 +7027,7 @@ DBGPerspective::get_breakpoint (const UString &a_file_name,
 const IDebugger::Breakpoint*
 DBGPerspective::get_breakpoint (const Address &a) const
 {
-    map<int, IDebugger::Breakpoint>::const_iterator iter;
+    map<string, IDebugger::Breakpoint>::const_iterator iter;
     for (iter = m_priv->breakpoints.begin ();
          iter != m_priv->breakpoints.end ();
          ++iter) {
@@ -7049,12 +7059,12 @@ DBGPerspective::delete_breakpoint ()
 }
 
 bool
-DBGPerspective::delete_breakpoint (int a_breakpoint_num)
+DBGPerspective::delete_breakpoint (const string &a_breakpoint_num)
 {
-    map<int, IDebugger::Breakpoint>::iterator iter =
+    map<string, IDebugger::Breakpoint>::iterator iter =
         m_priv->breakpoints.find (a_breakpoint_num);
     if (iter == m_priv->breakpoints.end ()) {
-        LOG_ERROR ("breakpoint " << (int) a_breakpoint_num << " not found");
+        LOG_ERROR ("breakpoint " << a_breakpoint_num << " not found");
         return false;
     }
     debugger ()->delete_breakpoint (a_breakpoint_num);
@@ -7118,9 +7128,9 @@ DBGPerspective::delete_visual_breakpoint (const UString &a_file_name,
 }
 
 void
-DBGPerspective::delete_visual_breakpoint (int a_breakpoint_num)
+DBGPerspective::delete_visual_breakpoint (const string &a_breakpoint_num)
 {
-    map<int, IDebugger::Breakpoint>::iterator iter =
+    map<string, IDebugger::Breakpoint>::iterator iter =
         m_priv->breakpoints.find (a_breakpoint_num);
     if (iter == m_priv->breakpoints.end ())
         return;
@@ -7128,7 +7138,7 @@ DBGPerspective::delete_visual_breakpoint (int a_breakpoint_num)
 }
 
 void
-DBGPerspective::delete_visual_breakpoint (map<int, IDebugger::Breakpoint>::iterator &a_i)
+DBGPerspective::delete_visual_breakpoint (map<string, IDebugger::Breakpoint>::iterator &a_i)
 {
     SourceEditor *source_editor = 0;
 
@@ -7164,7 +7174,7 @@ DBGPerspective::delete_visual_breakpoint (map<int, IDebugger::Breakpoint>::itera
         break;
     }
 
-    LOG_DD ("going to erase breakpoint number " << (int) a_i->first);
+    LOG_DD ("going to erase breakpoint number " << a_i->first);
     m_priv->breakpoints.erase (a_i);
 
 }
@@ -7175,8 +7185,8 @@ DBGPerspective::delete_visual_breakpoints ()
     if (m_priv->breakpoints.empty ())
         return;
 
-    map<int, IDebugger::Breakpoint> bps = m_priv->breakpoints;
-    map<int, IDebugger::Breakpoint>::iterator iter;
+    map<string, IDebugger::Breakpoint> bps = m_priv->breakpoints;
+    map<string, IDebugger::Breakpoint>::iterator iter;
 
     for (iter = bps.begin (); iter != bps.end (); ++iter)
         delete_visual_breakpoint (iter->first);
@@ -7262,7 +7272,7 @@ DBGPerspective::apply_decorations_to_source (SourceEditor *a_editor,
     THROW_IF_FAIL (a_editor->get_buffer_type ()
                    == SourceEditor::BUFFER_TYPE_SOURCE);
 
-    map<int, IDebugger::Breakpoint>::const_iterator it;
+    map<string, IDebugger::Breakpoint>::const_iterator it;
     for (it = m_priv->breakpoints.begin ();
          it != m_priv->breakpoints.end ();
          ++it) {
@@ -7308,7 +7318,7 @@ DBGPerspective::apply_decorations_to_asm (SourceEditor *a_editor,
 
     /// Apply breakpoint decorations to the breakpoints that are
     /// within the address range currently displayed.
-    map<int, IDebugger::Breakpoint>::const_iterator it;
+    map<string, IDebugger::Breakpoint>::const_iterator it;
     for (it = m_priv->breakpoints.begin ();
          it != m_priv->breakpoints.end ();
          ++it) {
@@ -7929,7 +7939,7 @@ DBGPerspective::toggle_breakpoint_enabled (const Address &a)
 }
 
 void
-DBGPerspective::toggle_breakpoint_enabled (int a_break_num,
+DBGPerspective::toggle_breakpoint_enabled (const string &a_break_num,
                                            bool a_enabled)
 {
     LOG_DD ("enabled: " << a_enabled);
diff --git a/src/persp/dbgperspective/nmv-dbg-perspective.h b/src/persp/dbgperspective/nmv-dbg-perspective.h
index 2cc4c47..5874e31 100644
--- a/src/persp/dbgperspective/nmv-dbg-perspective.h
+++ b/src/persp/dbgperspective/nmv-dbg-perspective.h
@@ -159,11 +159,11 @@ public:
     virtual void set_breakpoint (const IDebugger::Breakpoint &a_breakpoint) = 0;
 
     virtual void append_breakpoints
-            (const map<int, IDebugger::Breakpoint> &a_breaks) = 0;
+            (const map<string, IDebugger::Breakpoint> &a_breaks) = 0;
 
     virtual bool delete_breakpoint () = 0;
 
-    virtual bool delete_breakpoint (int a_breakpoint_num) = 0;
+    virtual bool delete_breakpoint (const string &a_breakpoint_num) = 0;
 
     virtual bool delete_breakpoint (const UString &a_file_uri,
                                     int a_linenum) = 0;
diff --git a/src/persp/dbgperspective/nmv-expr-monitor.cc b/src/persp/dbgperspective/nmv-expr-monitor.cc
index 306fd61..6b09a44 100644
--- a/src/persp/dbgperspective/nmv-expr-monitor.cc
+++ b/src/persp/dbgperspective/nmv-expr-monitor.cc
@@ -901,7 +901,7 @@ struct ExprMonitor::Priv
                        bool a_has_frame,
                        const IDebugger::Frame &a_frame,
                        int /*a_thread_id*/,
-                       int /*a_bp_num*/,
+                       const string& /*a_bp_num*/,
                        const UString &/*a_cookie*/)
     {
         LOG_FUNCTION_SCOPE_NORMAL_DD;
diff --git a/src/persp/dbgperspective/nmv-local-vars-inspector.cc 
b/src/persp/dbgperspective/nmv-local-vars-inspector.cc
index d0259fb..9dcf3cc 100644
--- a/src/persp/dbgperspective/nmv-local-vars-inspector.cc
+++ b/src/persp/dbgperspective/nmv-local-vars-inspector.cc
@@ -878,7 +878,7 @@ public:
                        bool a_has_frame,
                        const IDebugger::Frame &a_frame,
                        int /* a_thread_id */,
-                       int /* a_bp_num */,
+                       const string& /* a_bp_num */,
                        const UString &/*a_cookie*/)
     {
         LOG_FUNCTION_SCOPE_NORMAL_DD;
diff --git a/src/persp/dbgperspective/nmv-memory-view.cc b/src/persp/dbgperspective/nmv-memory-view.cc
index 2248870..303c18f 100644
--- a/src/persp/dbgperspective/nmv-memory-view.cc
+++ b/src/persp/dbgperspective/nmv-memory-view.cc
@@ -208,7 +208,7 @@ public:
                               bool /*a_has_frame*/,
                               const IDebugger::Frame& /*a_frame*/,
                               int /*a_thread_id*/,
-                              int /*bp num*/,
+                              const string& /*bp num*/,
                               const UString& /*a_cookie*/)
     {
         NEMIVER_TRY
diff --git a/src/persp/dbgperspective/nmv-registers-view.cc b/src/persp/dbgperspective/nmv-registers-view.cc
index 6fa0269..135838f 100644
--- a/src/persp/dbgperspective/nmv-registers-view.cc
+++ b/src/persp/dbgperspective/nmv-registers-view.cc
@@ -138,7 +138,7 @@ public:
                               bool,
                               const IDebugger::Frame &,
                               int,
-                              int,
+                              const string&,
                               const UString&)
     {
         LOG_FUNCTION_SCOPE_NORMAL_DD;
diff --git a/src/persp/dbgperspective/nmv-thread-list.cc b/src/persp/dbgperspective/nmv-thread-list.cc
index 613fbe8..ca38420 100644
--- a/src/persp/dbgperspective/nmv-thread-list.cc
+++ b/src/persp/dbgperspective/nmv-thread-list.cc
@@ -90,7 +90,7 @@ struct ThreadList::Priv {
                                      bool /*a_has_frame*/,
                                      const IDebugger::Frame &/*a_frame*/,
                                      int a_thread_id,
-                                     int /*bp_num*/,
+                                     const string &/*bp_num*/,
                                      const UString &/*a_cookie*/)
     {
         LOG_FUNCTION_SCOPE_NORMAL_DD;
diff --git a/tests/test-breakpoint.cc b/tests/test-breakpoint.cc
index 2757f2d..f760de7 100644
--- a/tests/test-breakpoint.cc
+++ b/tests/test-breakpoint.cc
@@ -29,8 +29,8 @@ on_program_finished_signal ()
 {
     MESSAGE ("program finished");
     MESSAGE ("nb of breakpoint hit: " <<  (int)nb_bp);
-    BOOST_REQUIRE(nb_bp == 5);
-    BOOST_REQUIRE(nb_stops > 5);
+    BOOST_REQUIRE(nb_bp == 1007);
+    BOOST_REQUIRE(nb_stops > 1007);
     loop->quit ();
 }
 
@@ -45,13 +45,13 @@ on_command_done_signal (const UString &a_command,
 }
 
 void
-on_breakpoints_set_signal (const std::map<int, IDebugger::Breakpoint> &a_breaks,
+on_breakpoints_set_signal (const std::map<string, IDebugger::Breakpoint> &a_breaks,
                            const UString &a_cookie)
 {
     if (a_cookie.empty ()) {}
 
     MESSAGE ("breakpoints set:");
-    std::map<int, IDebugger::Breakpoint>::const_iterator it;
+    std::map<string, IDebugger::Breakpoint>::const_iterator it;
     for (it = a_breaks.begin (); it != a_breaks.end () ; ++it) {
         MESSAGE ("<break><num>" << it->first <<"</num><line>"
                  << it->second.file_name () << ":" << it->second.line ()
@@ -82,7 +82,7 @@ on_stopped_signal (IDebugger::StopReason a_reason,
                    bool a_has_frame,
                    const IDebugger::Frame &a_frame,
                    int a_thread_id,
-                   int a_bp_num,
+                   const string &a_bp_num,
                    const UString &/*a_cookie*/,
                    IDebuggerSafePtr &a_debugger)
 {
@@ -129,8 +129,8 @@ on_stopped_signal (IDebugger::StopReason a_reason,
                 MESSAGE ("hit conditional breakpoint! bp number: "
                          << a_bp_num);
             }
-            map<int, IDebugger::Breakpoint>::const_iterator it;
-            map<int, IDebugger::Breakpoint>::const_iterator null_iter =
+            map<string, IDebugger::Breakpoint>::const_iterator it;
+            map<string, IDebugger::Breakpoint>::const_iterator null_iter =
                                     a_debugger->get_cached_breakpoints ().end ();
 
             if ((it = a_debugger->get_cached_breakpoints ().find (a_bp_num))
@@ -139,6 +139,9 @@ on_stopped_signal (IDebugger::StopReason a_reason,
                          << it->second.condition ());
             }
             a_debugger->do_continue ();
+        } else if (a_frame.function_name () == "Person::overload") {
+            MESSAGE ("stepping from Person::overload");
+            a_debugger->do_continue ();
         } else {
             BOOST_FAIL ("Stopped, for an unknown reason");
         }
@@ -251,6 +254,7 @@ test_main (int argc, char *argv[])
     debugger->set_breakpoint ("func1");
     debugger->set_breakpoint ("func2");
     debugger->set_breakpoint ("func4");
+    debugger->set_breakpoint ("Person::overload");
     debugger->run ();
     loop->run ();
 
diff --git a/tests/test-core.cc b/tests/test-core.cc
index 4040d10..cb73f0e 100644
--- a/tests/test-core.cc
+++ b/tests/test-core.cc
@@ -31,7 +31,7 @@ on_stopped_signal (IDebugger::StopReason a_reason,
                    bool a_has_frame,
                    const IDebugger::Frame &a_frame,
                    int a_thread_id,
-                   int /*bp num*/,
+                   const string &/*bp num*/,
                    const UString &/*a_cookie*/)
 {
     std::cout << "stopped, reason: " << (int)a_reason << " ";
diff --git a/tests/test-deref.cc b/tests/test-deref.cc
index 76de7f6..556f41c 100644
--- a/tests/test-deref.cc
+++ b/tests/test-deref.cc
@@ -99,7 +99,7 @@ on_stopped_signal (IDebugger::StopReason a_reason,
                    bool a_has_frame,
                    const IDebugger::Frame &a_frame,
                    int /*a_thread_id*/,
-                   int /*bp num*/,
+                   const string& /*bp num*/,
                    const UString &/*a_cookie*/,
                    IDebuggerSafePtr &a_debugger)
 {
diff --git a/tests/test-disassemble.cc b/tests/test-disassemble.cc
index 30942a5..d6089e8 100644
--- a/tests/test-disassemble.cc
+++ b/tests/test-disassemble.cc
@@ -108,7 +108,7 @@ on_stopped_signal (IDebugger::StopReason a_reason,
                    bool a_has_frame,
                    const IDebugger::Frame &a_frame,
                    int /*a_thread_id*/,
-                   int /*a_bp_num*/,
+                   const string &/*a_bp_num*/,
                    const UString &/*a_cookie*/)
 {
     MESSAGE ("stopped, reason is: "  << a_reason);
diff --git a/tests/test-gdbmi.cc b/tests/test-gdbmi.cc
index 29f2e3f..99db57e 100644
--- a/tests/test-gdbmi.cc
+++ b/tests/test-gdbmi.cc
@@ -165,6 +165,9 @@ static const char* gv_breakpoint1 =
 static const char* gv_breakpoint2 =
 
"bkpt={number=\"2\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"<PENDING>\",pending=\"/home/philip/nemiver:temp/main.cpp:78\",times=\"0\",original-location=\"/home/philip/nemiver:temp/main.cpp:78\"}";
 
+static const char* gv_breakpoint3 =
+    
"bkpt={number=\"2\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"<MULTIPLE>\",times=\"0\",original-location=\"error\"},{number=\"2.1\",enabled=\"y\",addr=\"0x000000000132d2f7\",func=\"error(char
 
const*,...)\",file=\"/home/dodji/git/gcc/PR56782/gcc/diagnostic.c\",fullname=\"/home/dodji/git/gcc/PR56782/gcc/diagnostic.c\",line=\"1038\"},{number=\"2.2\",enabled=\"y\",addr=\"0x00000032026f1490\",at=\"<error>\"}";
+
  const char *gv_disassemble0 =
  "asm_insns=[{address=\"0x08048dc3\",func-name=\"main\",offset=\"0\",inst=\"lea    
0x4(%esp),%ecx\"},{address=\"0x08048dc7\",func-name=\"main\",offset=\"4\",inst=\"and    
$0xfffffff0,%esp\"},{address=\"0x08048dca\",func-name=\"main\",offset=\"7\",inst=\"pushl  
-0x4(%ecx)\"},{address=\"0x08048dcd\",func-name=\"main\",offset=\"10\",inst=\"push   
%ebp\"},{address=\"0x08048dce\",func-name=\"main\",offset=\"11\",inst=\"mov    
%esp,%ebp\"},{address=\"0x08048dd0\",func-name=\"main\",offset=\"13\",inst=\"push   
%esi\"},{address=\"0x08048dd1\",func-name=\"main\",offset=\"14\",inst=\"push   
%ebx\"},{address=\"0x08048dd2\",func-name=\"main\",offset=\"15\",inst=\"push   
%ecx\"},{address=\"0x08048dd3\",func-name=\"main\",offset=\"16\",inst=\"sub    
$0x5c,%esp\"},{address=\"0x08048dd6\",func-name=\"main\",offset=\"19\",inst=\"lea    
-0x25(%ebp),%eax\"},{address=\"0x08048dd9\",func-name=\"main\",offset=\"22\",inst=\"mov    
%eax,(%esp)\"},{address=\"0x08048ddc\",func-name=\"main\",offset=\"25\",inst=\"call   0x8048be4 <_ZNSaIcEC1Ev 
plt>\"},{address=\"0x08048de1\",func-name=\"main\",offset=\"30\",inst=\"lea    
-0x25(%ebp),%eax\"},{address=\"0x08048de4\",func-name=\"main\",offset=\"33\",inst=\"mov    
%eax,0x8(%esp)\"},{address=\"0x08048de8\",func-name=\"main\",offset=\"37\",inst=\"movl   
$0x8049485,0x4(%esp)\"},{address=\"0x08048df0\",func-name=\"main\",offset=\"45\",inst=\"lea    
-0x2c(%ebp),%eax\"},{address=\"0x08048df3\",func-name=\"main\",offset=\"48\",inst=\"mov    
%eax,(%esp)\"},{address=\"0x08048df6\",func-name=\"main\",offset=\"51\",inst=\"call   0x8048b84 
<_ZNSsC1EPKcRKSaIcE plt>\"},{address=\"0x08048dfb\",func-name=\"main\",offset=\"56\",inst=\"lea    
-0x1d(%ebp),%eax\"},{address=\"0x08048dfe\",func-name=\"main\",offset=\"59\",inst=\"mov    
%eax,(%esp)\"},{address=\"0x08048e01\",func-name=\"main\",offset=\"62\",inst=\"call   0x8048be4 <_ZNSaIcEC1Ev 
plt>\"},{address=\"0x08048e06\",func-name=\"main\",offset=\"67\",inst=\"lea    
-0x1d(%ebp),%eax\"},{address=\"0x08048e09\",func-name=\"main\",offset=\"70\",inst=\"mov    
%eax,0x8(%esp)\"},{address=\"0x08048e0d\",func-name=\"main\",offset=\"74\",inst=\"movl   
$0x804948c,0x4(%esp)\"},{address=\"0x08048e15\",func-name=\"main\",offset=\"82\",inst=\"lea    
-0x24(%ebp),%eax\"},{address=\"0x08048e18\",func-name=\"main\",offset=\"85\",inst=\"mov    
%eax,(%esp)\"},{address=\"0x08048e1b\",func-name=\"main\",offset=\"88\",inst=\"call   0x8048b84 
<_ZNSsC1EPKcRKSaIcE plt>\"},{address=\"0x08048e20\",func-name=\"main\",offset=\"93\",inst=\"movl   
$0xf,0xc(%esp)\"},{address=\"0x08048e28\",func-name=\"main\",offset=\"101\",inst=\"lea    
-0x2c(%ebp),%eax\"},{address=\"0x08048e2b\",func-name=\"main\",offset=\"104\",inst=\"mov    
%eax,0x8(%esp)\"},{address=\"0x08048e2f\",func-name=\"main\",offset=\"108\",inst=\"lea    
-0x24(%ebp),%eax\"},{address=\"0x08048e32\",func-name=\"main\",offset=\"111\",inst=\"mov    
%eax,0x4(%esp)\"},{address=\"0x08048e36\",func-name=\"main\",offset=\"115\",inst=\"lea    
-0x38(%ebp),%eax\"},{address=\"0x08048e39\",func-name=\"main\",offset=\"118\",inst=\"mov    
%eax,(%esp)\"},{address=\"0x08048e3c\",func-name=\"main\",offset=\"121\",inst=\"call   0x8049178 
<Person>\"},{address=\"0x08048e41\",func-name=\"main\",offset=\"126\",inst=\"lea    
-0x24(%ebp),%eax\"},{address=\"0x08048e44\",func-name=\"main\",offset=\"129\",inst=\"mov    
%eax,-0x48(%ebp)\"},{address=\"0x08048e47\",func-name=\"main\",offset=\"132\",inst=\"mov    
-0x48(%ebp),%eax\"},{address=\"0x08048e4a\",func-name=\"main\",offset=\"135\",inst=\"mov    
%eax,(%esp)\"},{address=\"0x08048e4d\",func-name=\"main\",offset=\"138\",inst=\"call   0x8048bb4 <_ZNSsD1Ev 
plt>\"},{address=\"0x08048e52\",func-name=\"main\",offset=\"143\",inst=\"jmp    0x8048e79 
<main+182>\"},{address=\"0x08048e54\",func-name=\"main\",offset=\"145\",inst=\"mov    
%eax,-0x54(%ebp)\"},{address=\"0x08048e57\",func-name=\"main\",offset=\"148\",inst=\"mov    
%edx,-0x50(%ebp)\"},{address=\"0x08048e5a\",func-name=\"main\",offset=\"151\",inst=\"mov    
-0x50(%ebp),%esi\"},{address=\"0x08048e5d\",func-name=\"main\",offset=\"154\",inst=\"mov    
-0x54(%ebp),%ebx\"},{address=\"0x08048e60\",func-name=\"main\",offset=\"157\",inst=\"lea    
-0x24(%ebp),%eax\"},{address=\"0x08048e63\",func-name=\"main\",offset=\"160\",inst=\"mov    
%eax,-0x48(%ebp)\"},{address=\"0x08048e66\",func-name=\"main\",offset=\"163\",inst=\"mov    
-0x48(%ebp),%eax\"},{address=\"0x08048e69\",func-name=\"main\",offset=\"166\",inst=\"mov    
%eax,(%esp)\"},{address=\"0x08048e6c\",func-name=\"main\",offset=\"169\",inst=\"call   0x8048bb4 <_ZNSsD1Ev 
plt>\"},{address=\"0x08048e71\",func-name=\"main\",offset=\"174\",inst=\"mov    
%ebx,-0x54(%ebp)\"},{address=\"0x08048e74\",func-name=\"main\",offset=\"177\",inst=\"mov    
%esi,-0x50(%ebp)\"},{address=\"0x08048e77\",func-name=\"main\",offset=\"180\",inst=\"jmp    0x8048ebc 
<main+249>\"},{address=\"0x08048e79\",func-name=\"main\",offset=\"182\",inst=\"lea    
-0x1d(%ebp),%eax\"},{address=\"0x08048e7c\",func-name=\"main\",offset=\"185\",inst=\"mov    
%eax,(%esp)\"},{address=\"0x08048e7f\",func-name=\"main\",offset=\"188\",inst=\"call   0x8048b74 
<_ZNSaIcED1Ev plt>\"},{address=\"0x08048e84\",func-name=\"main\",offset=\"193\",inst=\"lea    
-0x2c(%ebp),%eax\"},{address=\"0x08048e87\",func-name=\"main\",offset=\"196\",inst=\"mov    
%eax,-0x4c(%ebp)\"},{address=\"0x08048e8a\",func-name=\"main\",offset=\"199\",inst=\"mov    
-0x4c(%ebp),%eax\"},{address=\"0x08048e8d\",func-name=\"main\",offset=\"202\",inst=\"mov    
%eax,(%esp)\"},{address=\"0x08048e90\",func-name=\"main\",offset=\"205\",inst=\"call   0x8048bb4 <_ZNSsD1Ev 
plt>\"},{address=\"0x08048e95\",func-name=\"main\",offset=\"210\",inst=\"jmp    0x8048ef2 
<main+303>\"},{address=\"0x08048e97\",func-name=\"main\",offset=\"212\",inst=\"mov    
%eax,-0x54(%ebp)\"},{address=\"0x08048e9a\",func-name=\"main\",offset=\"215\",inst=\"mov    
%edx,-0x50(%ebp)\"},{address=\"0x08048e9d\",func-name=\"main\",offset=\"218\",inst=\"mov    
-0x50(%ebp),%esi\"},{address=\"0x08048ea0\",func-name=\"main\",offset=\"221\",inst=\"mov    
-0x54(%ebp),%ebx\"},{address=\"0x08048ea3\",func-name=\"main\",offset=\"224\",inst=\"lea    
-0x38(%ebp),%eax\"},{address=\"0x08048ea6\",func-name=\"main\",offset=\"227\",inst=\"mov    
%eax,(%esp)\"},{address=\"0x08048ea9\",func-name=\"main\",offset=\"230\",inst=\"call   0x804921a 
<~Person>\"},{address=\"0x08048eae\",func-name=\"main\",offset=\"235\",inst=\"mov    
%ebx,-0x54(%ebp)\"},{address=\"0x08048eb1\",func-name=\"main\",offset=\"238\",inst=\"mov    
%esi,-0x50(%ebp)\"},{address=\"0x08048eb4\",func-name=\"main\",offset=\"241\",inst=\"jmp    0x8048ebc 
<main+249>\"},{address=\"0x08048eb6\",func-name=\"main\",offset=\"243\",inst=\"mov    
%eax,-0x54(%ebp)\"},{address=\"0x08048eb9\",func-name=\"main\",offset=\"246\",inst=\"mov    
%edx,-0x50(%ebp)\"},{address=\"0x08048ebc\",func-name=\"main\",offset=\"249\",inst=\"mov    
-0x50(%ebp),%esi\"},{address=\"0x08048ebf\",func-name=\"main\",offset=\"252\",inst=\"mov    
-0x54(%ebp),%ebx\"},{address=\"0x08048ec2\",func-name=\"main\",offset=\"255\",inst=\"lea    
-0x1d(%ebp),%eax\"},{address=\"0x08048ec5\",func-name=\"main\",offset=\"258\",inst=\"mov    
%eax,(%esp)\"},{address=\"0x08048ec8\",func-name=\"main\",offset=\"261\",inst=\"call   0x8048b74 
<_ZNSaIcED1Ev plt>\"},{address=\"0x08048ecd\",func-name=\"main\",offset=\"266\",inst=\"mov    
%ebx,-0x54(%ebp)\"},{address=\"0x08048ed0\",func-name=\"main\",offset=\"269\",inst=\"mov    
%esi,-0x50(%ebp)\"},{address=\"0x08048ed3\",func-name=\"main\",offset=\"272\",inst=\"mov    
-0x50(%ebp),%esi\"},{address=\"0x08048ed6\",func-name=\"main\",offset=\"275\",inst=\"mov    
-0x54(%ebp),%ebx\"},{address=\"0x08048ed9\",func-name=\"main\",offset=\"278\",inst=\"lea    
-0x2c(%ebp),%eax\"},{address=\"0x08048edc\",func-name=\"main\",offset=\"281\",inst=\"mov    
%eax,-0x4c(%ebp)\"},{address=\"0x08048edf\",func-name=\"main\",offset=\"284\",inst=\"mov    
-0x4c(%ebp),%eax\"},{address=\"0x08048ee2\",func-name=\"main\",offset=\"287\",inst=\"mov    
%eax,(%esp)\"},{address=\"0x08048ee5\",func-name=\"main\",offset=\"290\",inst=\"call   0x8048bb4 <_ZNSsD1Ev 
plt>\"},{address=\"0x08048eea\",func-name=\"main\",offset=\"295\",inst=\"mov    
%ebx,-0x54(%ebp)\"},{address=\"0x08048eed\",func-name=\"main\",offset=\"298\",inst=\"mov    
%esi,-0x50(%ebp)\"},{address=\"0x08048ef0\",func-name=\"main\",offset=\"301\",inst=\"jmp    0x8048f62 
<main+415>\"},{address=\"0x08048ef2\",func-name=\"main\",offset=\"303\",inst=\"lea    
-0x25(%ebp),%eax\"},{address=\"0x08048ef5\",func-name=\"main\",offset=\"306\",inst=\"mov    
%eax,(%esp)\"},{address=\"0x08048ef8\",func-name=\"main\",offset=\"309\",inst=\"call   0x8048b74 
<_ZNSaIcED1Ev plt>\"},{address=\"0x08048efd\",func-name=\"main\",offset=\"314\",inst=\"call   0x8048cd4 
<_Z5func1v>\"},{address=\"0x08048f02\",func-name=\"main\",offset=\"319\",inst=\"movl   
$0x2,0x4(%esp)\"},{address=\"0x08048f0a\",func-name=\"main\",offset=\"327\",inst=\"movl   
$0x1,(%esp)\"},{address=\"0x08048f11\",func-name=\"main\",offset=\"334\",inst=\"call   0x8048ce7 
<_Z5func2ii>\"},{address=\"0x08048f16\",func-name=\"main\",offset=\"339\",inst=\"lea    
-0x15(%ebp),%eax\"},{address=\"0x08048f19\",func-name=\"main\",offset=\"342\",inst=\"mov    
%eax,(%esp)\"},{address=\"0x08048f1c\",func-name=\"main\",offset=\"345\",inst=\"call   0x8048be4 
<_ZNSaIcEC1Ev plt>\"},{address=\"0x08048f21\",func-name=\"main\",offset=\"350\",inst=\"lea    
-0x15(%ebp),%eax\"},{address=\"0x08048f24\",func-name=\"main\",offset=\"353\",inst=\"mov    
%eax,0x8(%esp)\"},{address=\"0x08048f28\",func-name=\"main\",offset=\"357\",inst=\"movl   
$0x8049490,0x4(%esp)\"},{address=\"0x08048f30\",func-name=\"main\",offset=\"365\",inst=\"lea    
-0x1c(%ebp),%eax\"},{address=\"0x08048f33\",func-name=\"main\",offset=\"368\",inst=\"mov    
%eax,(%esp)\"},{address=\"0x08048f36\",func-name=\"main\",offset=\"371\",inst=\"call   0x8048b84 
<_ZNSsC1EPKcRKSaIcE plt>\"},{address=\"0x08048f3b\",func-name=\"main\",offset=\"376\",inst=\"jmp    0x8048f84 
<main+449>\"},{address=\"0x08048f3d\",func-name=\"main\",offset=\"378\",inst=\"mov    
%eax,-0x54(%ebp)\"},{address=\"0x08048f40\",func-name=\"main\",offset=\"381\",inst=\"mov    
%edx,-0x50(%ebp)\"},{address=\"0x08048f43\",func-name=\"main\",offset=\"384\",inst=\"mov    
-0x50(%ebp),%esi\"},{address=\"0x08048f46\",func-name=\"main\",offset=\"387\",inst=\"mov    
-0x54(%ebp),%ebx\"},{address=\"0x08048f49\",func-name=\"main\",offset=\"390\",inst=\"lea    
-0x38(%ebp),%eax\"},{address=\"0x08048f4c\",func-name=\"main\",offset=\"393\",inst=\"mov    
%eax,(%esp)\"},{address=\"0x08048f4f\",func-name=\"main\",offset=\"396\",inst=\"call   0x804921a 
<~Person>\"},{address=\"0x08048f54\",func-name=\"main\",offset=\"401\",inst=\"mov    
%ebx,-0x54(%ebp)\"},{address=\"0x08048f57\",func-name=\"main\",offset=\"404\",inst=\"mov    
%esi,-0x50(%ebp)\"},{address=\"0x08048f5a\",func-name=\"main\",offset=\"407\",inst=\"jmp    0x8048f62 
<main+415>\"},{address=\"0x08048f5c\",func-name=\"main\",offset=\"409\",inst=\"mov    
%eax,-0x54(%ebp)\"},{address=\"0x08048f5f\",func-name=\"main\",offset=\"412\",inst=\"mov    
%edx,-0x50(%ebp)\"},{address=\"0x08048f62\",func-name=\"main\",offset=\"415\",inst=\"mov    
-0x50(%ebp),%esi\"},{address=\"0x08048f65\",func-name=\"main\",offset=\"418\",inst=\"mov    
-0x54(%ebp),%ebx\"},{address=\"0x08048f68\",func-name=\"main\",offset=\"421\",inst=\"lea    
-0x25(%ebp),%eax\"},{address=\"0x08048f6b\",func-name=\"main\",offset=\"424\",inst=\"mov    
%eax,(%esp)\"},{address=\"0x08048f6e\",func-name=\"main\",offset=\"427\",inst=\"call   0x8048b74 
<_ZNSaIcED1Ev plt>\"},{address=\"0x08048f73\",func-name=\"main\",offset=\"432\",inst=\"mov    
%ebx,-0x54(%ebp)\"},{address=\"0x08048f76\",func-name=\"main\",offset=\"435\",inst=\"mov    
%esi,-0x50(%ebp)\"},{address=\"0x08048f79\",func-name=\"main\",offset=\"438\",inst=\"mov    
-0x54(%ebp),%eax\"},{address=\"0x08048f7c\",func-name=\"main\",offset=\"441\",inst=\"mov    
%eax,(%esp)\"},{address=\"0x08048f7f\",func-name=\"main\",offset=\"444\",inst=\"call   0x8048bd4 
<_Unwind_Resume plt>\"},{address=\"0x08048f84\",func-name=\"main\",offset=\"449\",inst=\"lea    
-0x1c(%ebp),%eax\"},{address=\"0x08048f87\",func-name=\"main\",offset=\"452\",inst=\"mov    
%eax,0x4(%esp)\"},{address=\"0x08048f8b\",func-name=\"main\",offset=\"456\",inst=\"lea    
-0x38(%ebp),%eax\"},{address=\"0x08048f8e\",func-name=\"main\",offset=\"459\",inst=\"mov    
%eax,(%esp)\"},{address=\"0x08048f91\",func-name=\"main\",offset=\"462\",inst=\"call   0x8049140 
<_ZN6Person14set_first_nameERKSs>\"},{address=\"0x08048f96\",func-name=\"main\",offset=\"467\",inst=\"lea    
-0x1c(%ebp),%eax\"},{address=\"0x08048f99\",func-name=\"main\",offset=\"470\",inst=\"mov    
%eax,-0x44(%ebp)\"},{address=\"0x08048f9c\",func-name=\"main\",offset=\"473\",inst=\"mov    
-0x44(%ebp),%eax\"},{address=\"0x08048f9f\",func-name=\"main\",offset=\"476\",inst=\"mov    
%eax,(%esp)\"},{address=\"0x08048fa2\",func-name=\"main\",offset=\"479\",inst=\"call   0x8048bb4 <_ZNSsD1Ev 
plt>\"},{address=\"0x08048fa7\",func-name=\"main\",offset=\"484\",inst=\"jmp    0x8048fce 
<main+523>\"},{address=\"0x08048fa9\",func-name=\"main\",offset=\"486\",inst=\"mov    
%eax,-0x54(%ebp)\"},{address=\"0x08048fac\",func-name=\"main\",offset=\"489\",inst=\"mov    
%edx,-0x50(%ebp)\"},{address=\"0x08048faf\",func-name=\"main\",offset=\"492\",inst=\"mov    
-0x50(%ebp),%esi\"},{address=\"0x08048fb2\",func-name=\"main\",offset=\"495\",inst=\"mov    
-0x54(%ebp),%ebx\"},{address=\"0x08048fb5\",func-name=\"main\",offset=\"498\",inst=\"lea    
-0x1c(%ebp),%eax\"},{address=\"0x08048fb8\",func-name=\"main\",offset=\"501\",inst=\"mov    
%eax,-0x44(%ebp)\"},{address=\"0x08048fbb\",func-name=\"main\",offset=\"504\",inst=\"mov    
-0x44(%ebp),%eax\"},{address=\"0x08048fbe\",func-name=\"main\",offset=\"507\",inst=\"mov    
%eax,(%esp)\"},{address=\"0x08048fc1\",func-name=\"main\",offset=\"510\",inst=\"call   0x8048bb4 <_ZNSsD1Ev 
plt>\"},{address=\"0x08048fc6\",func-name=\"main\",offset=\"515\",inst=\"mov    
%ebx,-0x54(%ebp)\"},{address=\"0x08048fc9\",func-name=\"main\",offset=\"518\",inst=\"mov    
%esi,-0x50(%ebp)\"},{address=\"0x08048fcc\",func-name=\"main\",offset=\"521\",inst=\"jmp    0x8049006 
<main+579>\"},{address=\"0x08048fce\",func-name=\"main\",offset=\"523\",inst=\"lea    
-0x15(%ebp),%eax\"},{address=\"0x08048fd1\",func-name=\"main\",offset=\"526\",inst=\"mov    
%eax,(%esp)\"},{address=\"0x08048fd4\",func-name=\"main\",offset=\"529\",inst=\"call   0x8048b74 
<_ZNSaIcED1Ev plt>\"},{address=\"0x08048fd9\",func-name=\"main\",offset=\"534\",inst=\"lea    
-0xd(%ebp),%eax\"},{address=\"0x08048fdc\",func-name=\"main\",offset=\"537\",inst=\"mov    
%eax,(%esp)\"},{address=\"0x08048fdf\",func-name=\"main\",offset=\"540\",inst=\"call   0x8048be4 
<_ZNSaIcEC1Ev plt>\"},{address=\"0x08048fe4\",func-name=\"main\",offset=\"545\",inst=\"lea    
-0xd(%ebp),%eax\"},{address=\"0x08048fe7\",func-name=\"main\",offset=\"548\",inst=\"mov    
%eax,0x8(%esp)\"},{address=\"0x08048feb\",func-name=\"main\",offset=\"552\",inst=\"movl   
$0x8049494,0x4(%esp)\"},{address=\"0x08048ff3\",func-name=\"main\",offset=\"560\",inst=\"lea    
-0x14(%ebp),%eax\"},{address=\"0x08048ff6\",func-name=\"main\",offset=\"563\",inst=\"mov    
%eax,(%esp)\"},{address=\"0x08048ff9\",func-name=\"main\",offset=\"566\",inst=\"call   0x8048b84 
<_ZNSsC1EPKcRKSaIcE plt>\"},{address=\"0x08048ffe\",func-name=\"main\",offset=\"571\",inst=\"jmp    0x8049022 
<main+607>\"},{address=\"0x08049000\",func-name=\"main\",offset=\"573\",inst=\"mov    
%eax,-0x54(%ebp)\"},{address=\"0x08049003\",func-name=\"main\",offset=\"576\",inst=\"mov    
%edx,-0x50(%ebp)\"},{address=\"0x08049006\",func-name=\"main\",offset=\"579\",inst=\"mov    
-0x50(%ebp),%esi\"},{address=\"0x08049009\",func-name=\"main\",offset=\"582\",inst=\"mov    
-0x54(%ebp),%ebx\"},{address=\"0x0804900c\",func-name=\"main\",offset=\"585\",inst=\"lea    
-0x15(%ebp),%eax\"},{address=\"0x0804900f\",func-name=\"main\",offset=\"588\",inst=\"mov    
%eax,(%esp)\"},{address=\"0x08049012\",func-name=\"main\",offset=\"591\",inst=\"call   0x8048b74 
<_ZNSaIcED1Ev plt>\"},{address=\"0x08049017\",func-name=\"main\",offset=\"596\",inst=\"mov    
%ebx,-0x54(%ebp)\"},{address=\"0x0804901a\",func-name=\"main\",offset=\"599\",inst=\"mov    
%esi,-0x50(%ebp)\"},{address=\"0x0804901d\",func-name=\"main\",offset=\"602\",inst=\"jmp    0x80490fa 
<main+823>\"},{address=\"0x08049022\",func-name=\"main\",offset=\"607\",inst=\"lea    
-0x14(%ebp),%eax\"},{address=\"0x08049025\",func-name=\"main\",offset=\"610\",inst=\"mov    
%eax,0x4(%esp)\"},{address=\"0x08049029\",func-name=\"main\",offset=\"614\",inst=\"lea    
-0x38(%ebp),%eax\"},{address=\"0x0804902c\",func-name=\"main\",offset=\"617\",inst=\"mov    
%eax,(%esp)\"},{address=\"0x0804902f\",func-name=\"main\",offset=\"620\",inst=\"call   0x804915a 
<_ZN6Person15set_family_nameERKSs>\"},{address=\"0x08049034\",func-name=\"main\",offset=\"625\",inst=\"lea    
-0x14(%ebp),%eax\"},{address=\"0x08049037\",func-name=\"main\",offset=\"628\",inst=\"mov    
%eax,-0x40(%ebp)\"},{address=\"0x0804903a\",func-name=\"main\",offset=\"631\",inst=\"mov    
-0x40(%ebp),%eax\"},{address=\"0x0804903d\",func-name=\"main\",offset=\"634\",inst=\"mov    
%eax,(%esp)\"},{address=\"0x08049040\",func-name=\"main\",offset=\"637\",inst=\"call   0x8048bb4 <_ZNSsD1Ev 
plt>\"},{address=\"0x08049045\",func-name=\"main\",offset=\"642\",inst=\"jmp    0x804906c 
<main+681>\"},{address=\"0x08049047\",func-name=\"main\",offset=\"644\",inst=\"mov    
%eax,-0x54(%ebp)\"},{address=\"0x0804904a\",func-name=\"main\",offset=\"647\",inst=\"mov    
%edx,-0x50(%ebp)\"},{address=\"0x0804904d\",func-name=\"main\",offset=\"650\",inst=\"mov    
-0x50(%ebp),%esi\"},{address=\"0x08049050\",func-name=\"main\",offset=\"653\",inst=\"mov    
-0x54(%ebp),%ebx\"},{address=\"0x08049053\",func-name=\"main\",offset=\"656\",inst=\"lea    
-0x14(%ebp),%eax\"},{address=\"0x08049056\",func-name=\"main\",offset=\"659\",inst=\"mov    
%eax,-0x40(%ebp)\"},{address=\"0x08049059\",func-name=\"main\",offset=\"662\",inst=\"mov    
-0x40(%ebp),%eax\"},{address=\"0x0804905c\",func-name=\"main\",offset=\"665\",inst=\"mov    
%eax,(%esp)\"},{address=\"0x0804905f\",func-name=\"main\",offset=\"668\",inst=\"call   0x8048bb4 <_ZNSsD1Ev 
plt>\"},{address=\"0x08049064\",func-name=\"main\",offset=\"673\",inst=\"mov    
%ebx,-0x54(%ebp)\"},{address=\"0x08049067\",func-name=\"main\",offset=\"676\",inst=\"mov    
%esi,-0x50(%ebp)\"},{address=\"0x0804906a\",func-name=\"main\",offset=\"679\",inst=\"jmp    0x804908a 
<main+711>\"},{address=\"0x0804906c\",func-name=\"main\",offset=\"681\",inst=\"lea    
-0xd(%ebp),%eax\"},{address=\"0x0804906f\",func-name=\"main\",offset=\"684\",inst=\"mov    
%eax,(%esp)\"},{address=\"0x08049072\",func-name=\"main\",offset=\"687\",inst=\"call   0x8048b74 
<_ZNSaIcED1Ev plt>\"},{address=\"0x08049077\",func-name=\"main\",offset=\"692\",inst=\"lea    
-0x38(%ebp),%eax\"},{address=\"0x0804907a\",func-name=\"main\",offset=\"695\",inst=\"mov    
%eax,(%esp)\"},{address=\"0x0804907d\",func-name=\"main\",offset=\"698\",inst=\"call   0x8049272 
<_ZN6Person7do_thisEv>\"},{address=\"0x08049082\",func-name=\"main\",offset=\"703\",inst=\"jmp    0x80490a3 
<main+736>\"},{address=\"0x08049084\",func-name=\"main\",offset=\"705\",inst=\"mov    
%eax,-0x54(%ebp)\"},{address=\"0x08049087\",func-name=\"main\",offset=\"708\",inst=\"mov    
%edx,-0x50(%ebp)\"},{address=\"0x0804908a\",func-name=\"main\",offset=\"711\",inst=\"mov    
-0x50(%ebp),%esi\"},{address=\"0x0804908d\",func-name=\"main\",offset=\"714\",inst=\"mov    
-0x54(%ebp),%ebx\"},{address=\"0x08049090\",func-name=\"main\",offset=\"717\",inst=\"lea    
-0xd(%ebp),%eax\"},{address=\"0x08049093\",func-name=\"main\",offset=\"720\",inst=\"mov    
%eax,(%esp)\"},{address=\"0x08049096\",func-name=\"main\",offset=\"723\",inst=\"call   0x8048b74 
<_ZNSaIcED1Ev plt>\"},{address=\"0x0804909b\",func-name=\"main\",offset=\"728\",inst=\"mov    
%ebx,-0x54(%ebp)\"},{address=\"0x0804909e\",func-name=\"main\",offset=\"731\",inst=\"mov    
%esi,-0x50(%ebp)\"},{address=\"0x080490a1\",func-name=\"main\",offset=\"734\",inst=\"jmp    0x80490fa 
<main+823>\"},{address=\"0x080490a3\",func-name=\"main\",offset=\"736\",inst=\"lea    
-0x38(%ebp),%eax\"},{address=\"0x080490a6\",func-name=\"main\",offset=\"739\",inst=\"mov    
%eax,(%esp)\"},{address=\"0x080490a9\",func-name=\"main\",offset=\"742\",inst=\"call   0x804911c 
<_ZN6Person8overloadEv>\"},{address=\"0x080490ae\",func-name=\"main\",offset=\"747\",inst=\"movl   
$0x0,0x4(%esp)\"},{address=\"0x080490b6\",func-name=\"main\",offset=\"755\",inst=\"lea    
-0x38(%ebp),%eax\"},{address=\"0x080490b9\",func-name=\"main\",offset=\"758\",inst=\"mov    
%eax,(%esp)\"},{address=\"0x080490bc\",func-name=\"main\",offset=\"761\",inst=\"call   0x8049130 
<_ZN6Person8overloadEi>\"},{address=\"0x080490c1\",func-name=\"main\",offset=\"766\",inst=\"lea    
-0x38(%ebp),%eax\"},{address=\"0x080490c4\",func-name=\"main\",offset=\"769\",inst=\"mov    
%eax,(%esp)\"},{address=\"0x080490c7\",func-name=\"main\",offset=\"772\",inst=\"call   0x8048db0 
<_Z5func3R6Person>\"},{address=\"0x080490cc\",func-name=\"main\",offset=\"777\",inst=\"lea    
-0x38(%ebp),%eax\"},{address=\"0x080490cf\",func-name=\"main\",offset=\"780\",inst=\"mov    
%eax,(%esp)\"},{address=\"0x080490d2\",func-name=\"main\",offset=\"783\",inst=\"call   0x8048cff 
<_Z5func4R6Person>\"},{address=\"0x080490d7\",func-name=\"main\",offset=\"788\",inst=\"mov    
$0x0,%ebx\"},{address=\"0x080490dc\",func-name=\"main\",offset=\"793\",inst=\"lea    
-0x38(%ebp),%eax\"},{address=\"0x080490df\",func-name=\"main\",offset=\"796\",inst=\"mov    
%eax,(%esp)\"},{address=\"0x080490e2\",func-name=\"main\",offset=\"799\",inst=\"call   0x804921a 
<~Person>\"},{address=\"0x080490e7\",func-name=\"main\",offset=\"804\",inst=\"mov    
%ebx,%eax\"},{address=\"0x080490e9\",func-name=\"main\",offset=\"806\",inst=\"add    
$0x5c,%esp\"},{address=\"0x080490ec\",func-name=\"main\",offset=\"809\",inst=\"pop    
%ecx\"},{address=\"0x080490ed\",func-name=\"main\",offset=\"810\",inst=\"pop    
%ebx\"},{address=\"0x080490ee\",func-name=\"main\",offset=\"811\",inst=\"pop    
%esi\"},{address=\"0x080490ef\",func-name=\"main\",offset=\"812\",inst=\"pop    
%ebp\"},{address=\"0x080490f0\",func-name=\"main\",offset=\"813\",inst=\"lea    
-0x4(%ecx),%esp\"},{address=\"0x080490f3\",func-name=\"main\",offset=\"816\",inst=\"ret    
\"},{address=\"0x080490f4\",func-name=\"main\",offset=\"817\",inst=\"mov    
%eax,-0x54(%ebp)\"},{address=\"0x080490f7\",func-name=\"main\",offset=\"820\",inst=\"mov    
%edx,-0x50(%ebp)\"},{address=\"0x080490fa\",func-name=\"main\",offset=\"823\",inst=\"mov    
-0x50(%ebp),%esi\"},{address=\"0x080490fd\",func-name=\"main\",offset=\"826\",inst=\"mov    
-0x54(%ebp),%ebx\"},{address=\"0x08049100\",func-name=\"main\",offset=\"829\",inst=\"lea    
-0x38(%ebp),%eax\"},{address=\"0x08049103\",func-name=\"main\",offset=\"832\",inst=\"mov    
%eax,(%esp)\"},{address=\"0x08049106\",func-name=\"main\",offset=\"835\",inst=\"call   0x804921a 
<~Person>\"},{address=\"0x0804910b\",func-name=\"main\",offset=\"840\",inst=\"mov    
%ebx,-0x54(%ebp)\"},{address=\"0x0804910e\",func-name=\"main\",offset=\"843\",inst=\"mov    
%esi,-0x50(%ebp)\"},{address=\"0x08049111\",func-name=\"main\",offset=\"846\",inst=\"mov    
-0x54(%ebp),%eax\"},{address=\"0x08049114\",func-name=\"main\",offset=\"849\",inst=\"mov    
%eax,(%esp)\"},{address=\"0x08049117\",func-name=\"main\",offset=\"852\",inst=\"call   0x8048bd4 
<_Unwind_Resume plt>\"}]";
   
@@ -852,16 +855,16 @@ test_gdbmi_result ()
 void
 test_breakpoint_table ()
 {
-    std::map<int, IDebugger::Breakpoint> breakpoints;
+    std::map<string, IDebugger::Breakpoint> breakpoints;
     UString::size_type cur = 0;
 
     GDBMIParser parser (gv_breakpoint_table0);
     BOOST_REQUIRE (parser.parse_breakpoint_table (cur, cur, breakpoints));
     BOOST_REQUIRE_EQUAL (breakpoints.size (), 1u);
-    std::map<int, IDebugger::Breakpoint>::const_iterator iter;
-    iter = breakpoints.find (1);
+    std::map<string, IDebugger::Breakpoint>::const_iterator iter;
+    iter = breakpoints.find ("1");
     BOOST_REQUIRE (iter != breakpoints.end ());
-    BOOST_REQUIRE_EQUAL (iter->second.number (), 1);
+    BOOST_REQUIRE_EQUAL (iter->second.number (), "1");
     BOOST_REQUIRE (iter->second.enabled ());
     BOOST_REQUIRE_EQUAL (iter->second.address (), "0x08081566");
     BOOST_REQUIRE_EQUAL (iter->second.function (), "main");
@@ -887,9 +890,9 @@ test_breakpoint_table ()
     parser.push_input (gv_breakpoint_table4);
     parser.set_mode (GDBMIParser::BROKEN_MODE);
     BOOST_REQUIRE (parser.parse_breakpoint_table (cur, cur, breakpoints));
-    BOOST_REQUIRE_EQUAL (breakpoints[2].file_full_name (),
+    BOOST_REQUIRE_EQUAL (breakpoints["2"].file_full_name (),
                          "/home/philip/nemiver:temp/main.cpp");
-    BOOST_REQUIRE_EQUAL (breakpoints[2].line (), 78);
+    BOOST_REQUIRE_EQUAL (breakpoints["2"].line (), 78);
 
     cur = 0, cur = 0, breakpoints.clear ();
     parser.push_input (gv_breakpoint_table5);
@@ -923,6 +926,15 @@ test_breakpoint ()
     BOOST_REQUIRE_EQUAL (breakpoint.file_full_name (),
                          "/home/philip/nemiver:temp/main.cpp");
     BOOST_REQUIRE_EQUAL (breakpoint.line (), 78);
+
+    parser.push_input (gv_breakpoint3);
+    breakpoint.clear ();
+    is_ok = parser.parse_breakpoint (0, cur, breakpoint);
+    BOOST_REQUIRE (is_ok);
+    BOOST_REQUIRE (breakpoint.has_multiple_locations ());
+    BOOST_REQUIRE_EQUAL (breakpoint.sub_breakpoints ().size (), 2);
+    BOOST_REQUIRE_EQUAL (breakpoint.sub_breakpoints ()[0].number (), "2.1");
+    BOOST_REQUIRE_EQUAL (breakpoint.sub_breakpoints ()[1].number (), "2.2");
 }
 
 void
diff --git a/tests/test-local-vars-list.cc b/tests/test-local-vars-list.cc
index b0584e6..03cf609 100644
--- a/tests/test-local-vars-list.cc
+++ b/tests/test-local-vars-list.cc
@@ -24,7 +24,7 @@ on_stopped_signal (IDebugger::StopReason a_reason,
                    bool a_has_frame,
                    const IDebugger::Frame &a_frame,
                    int /*a_thread_id*/,
-                   int /*a_bp_num*/,
+                   const string &/*a_bp_num*/,
                    const UString &/*a_cookie*/,
                    const IVarListSafePtr a_var_list)
 {
diff --git a/tests/test-pretty-print.cc b/tests/test-pretty-print.cc
index d345a7b..a3c8a90 100644
--- a/tests/test-pretty-print.cc
+++ b/tests/test-pretty-print.cc
@@ -105,7 +105,7 @@ static void
 on_stopped_signal (IDebugger::StopReason /*a_reason*/,
                    bool a_has_frame,
                    const IDebugger::Frame &a_frame,
-                   int, int,
+                   int, const string &,
                    const UString &/*a_cookie*/,
                    IDebuggerSafePtr &a_debugger)
 {
diff --git a/tests/test-threads.cc b/tests/test-threads.cc
index 9decf29..b08723b 100644
--- a/tests/test-threads.cc
+++ b/tests/test-threads.cc
@@ -34,7 +34,7 @@ on_stopped_signal (IDebugger::StopReason a_reason,
                    bool /*a_has_frame*/,
                    const IDebugger::Frame &/*a_frame*/,
                    int /*a_thread_id*/,
-                   int /*a_bp_num*/,
+                   const string &/*a_bp_num*/,
                    const UString &/*a_cookie*/,
                    IDebuggerSafePtr &a_debugger)
 {
diff --git a/tests/test-types.cc b/tests/test-types.cc
index 37aa74e..5a412f9 100644
--- a/tests/test-types.cc
+++ b/tests/test-types.cc
@@ -54,7 +54,7 @@ on_stopped_signal (IDebugger::StopReason,
                    bool a_has_frame,
                    const IDebugger::Frame &a_frame,
                    int,
-                   int,
+                   const string &,
                    const UString&,
                    IDebuggerSafePtr a_debugger)
 {
diff --git a/tests/test-var-list.cc b/tests/test-var-list.cc
index f022017..dd3b9a1 100644
--- a/tests/test-var-list.cc
+++ b/tests/test-var-list.cc
@@ -48,7 +48,7 @@ on_stopped_signal (IDebugger::StopReason a_reason,
                    bool a_has_frame,
                    const IDebugger::Frame &a_frame,
                    int /*a_thread_id*/,
-                   int /*bp number*/,
+                   const string & /*bp number*/,
                    const UString &/*a_cookie*/,
                    IDebuggerSafePtr &a_debugger)
 {
diff --git a/tests/test-var-path-expr.cc b/tests/test-var-path-expr.cc
index 9d6208d..ed2c325 100644
--- a/tests/test-var-path-expr.cc
+++ b/tests/test-var-path-expr.cc
@@ -55,13 +55,13 @@ on_variable_deleted_signal (const IDebugger::VariableSafePtr a_var,
 }
 
 static void
-on_breakpoints_set_signal (const std::map<int, IDebugger::Breakpoint> &a_breaks,
+on_breakpoints_set_signal (const std::map<string, IDebugger::Breakpoint> &a_breaks,
                            const UString &a_cookie)
 {
     if (a_cookie.empty ()) {}
 
     MESSAGE ("breakpoints set:");
-    std::map<int, IDebugger::Breakpoint>::const_iterator it;
+    std::map<string, IDebugger::Breakpoint>::const_iterator it;
     for (it = a_breaks.begin (); it != a_breaks.end () ; ++it) {
         MESSAGE ("<break><num>" << it->first <<"</num><line>"
                  << it->second.file_name () << ":" << it->second.line ()
@@ -124,7 +124,7 @@ on_stopped_signal (IDebugger::StopReason a_reason,
                    bool /*a_has_frame*/,
                    const IDebugger::Frame &a_frame,
                    int /*a_thread_id*/,
-                   int /*a_bp_num*/,
+                   const string &/*a_bp_num*/,
                    const UString &/*a_cookie*/,
                    IDebuggerSafePtr a_debugger)
 {
diff --git a/tests/test-var-walker.cc b/tests/test-var-walker.cc
index bdc18ca..fa4f9da 100644
--- a/tests/test-var-walker.cc
+++ b/tests/test-var-walker.cc
@@ -98,7 +98,7 @@ on_stopped_signal (IDebugger::StopReason a_reason,
                    bool a_has_frame,
                    const IDebugger::Frame &a_frame,
                    int /*a_thread_id*/,
-                   int /*bp num*/,
+                   const string & /*bp num*/,
                    const UString &/*a_cookie*/,
                    IDebuggerSafePtr &a_debugger)
 {
diff --git a/tests/test-variable-format.cc b/tests/test-variable-format.cc
index ef914a8..bd67c94 100644
--- a/tests/test-variable-format.cc
+++ b/tests/test-variable-format.cc
@@ -76,7 +76,7 @@ on_stopped_signal (IDebugger::StopReason a_reason,
                    bool /*a_has_frame*/,
                    const IDebugger::Frame &a_frame,
                    int /*a_thread_id*/,
-                   int /*bp num*/,
+                   const string &/*bp num*/,
                    const UString &/*a_cookie*/,
                    IDebuggerSafePtr &a_debugger)
 {
diff --git a/tests/test-varobj-walker.cc b/tests/test-varobj-walker.cc
index bdc1a8d..80bc78b 100644
--- a/tests/test-varobj-walker.cc
+++ b/tests/test-varobj-walker.cc
@@ -122,7 +122,7 @@ on_stopped_signal (IDebugger::StopReason a_reason,
                    bool /*a_has_frame*/,
                    const IDebugger::Frame &a_frame,
                    int /*a_thread_id*/,
-                   int /*bp num*/,
+                   const string & /*bp num*/,
                    const UString &/*a_cookie*/,
                    IDebuggerSafePtr &a_debugger)
 {
diff --git a/tests/test-vars.cc b/tests/test-vars.cc
index 6593bd0..fd3786b 100644
--- a/tests/test-vars.cc
+++ b/tests/test-vars.cc
@@ -215,7 +215,7 @@ on_stopped_signal (IDebugger::StopReason /*a_reason*/,
                    bool a_has_frame,
                    const IDebugger::Frame &a_frame,
                    int,
-                   int,
+                   const string&,
                    const UString &/*a_cookie*/,
                    IDebuggerSafePtr &a_debugger)
 {
diff --git a/tests/test-watchpoint.cc b/tests/test-watchpoint.cc
index 49f99e0..1ec047a 100644
--- a/tests/test-watchpoint.cc
+++ b/tests/test-watchpoint.cc
@@ -31,13 +31,13 @@ on_program_finished_signal ()
 }
 
 void
-on_breakpoints_set_signal (const std::map<int, IDebugger::Breakpoint> &a_breaks,
+on_breakpoints_set_signal (const std::map<string, IDebugger::Breakpoint> &a_breaks,
                            const UString &a_cookie)
 {
     if (a_cookie.empty ()) {}
 
     MESSAGE ("breakpoints set:");
-    std::map<int, IDebugger::Breakpoint>::const_iterator it;
+    std::map<string, IDebugger::Breakpoint>::const_iterator it;
     for (it = a_breaks.begin (); it != a_breaks.end () ; ++it) {
         MESSAGE ("<break><num>" << it->first <<"</num><line>"
                  << it->second.file_name () << ":" << it->second.line ()
@@ -50,7 +50,7 @@ on_stopped_signal (IDebugger::StopReason a_reason,
                    bool a_has_frame,
                    const IDebugger::Frame &a_frame,
                    int /*a_thread_id*/,
-                   int /*a_bp_num*/,
+                   const string &/*a_bp_num*/,
                    const UString &/*a_cookie*/,
                    IDebuggerSafePtr &a_debugger)
 {
-- 
1.8.2.1


-- 
                Dodji


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