[nemiver/count-point: 1/2] Countpoints support



commit fb3a23ca11959a1daf9b1b39cf08902fc2047a65
Author: Dodji Seketeli <dodji seketeli org>
Date:   Mon Sep 27 13:39:18 2010 +0200

    Countpoints support
    
    	* src/dbgengine/nmv-i-debugger.h
    	(IDebugger::Breakpoint::Type)<COUNTPOINT_TYPE>: New type of
    	breakpoint.
    	(IDebugger::set_breakpoint): Allow the ignore_count parm of to be
    	negative. When passed a negative ignore count,
    	IDebugger::set_breakpoint will set a countpoint.
    	* src/dbgengine/nmv-debugger-utils.[h,cc] (is_countpoint): New fn.
    	* src/dbgengine/nmv-gdb-engine.h (maybe_handle_countpoint): New
    	fn.
    	(GDB::set_breakpoint): Allow ignore_count to be negative.
    	* src/dbgengine/nmv-gdb-engine.cc
    	(GDBEngine::set_breakpoint): When called with a negative ignore
    	count, set the GDB-side breakpoint using a generic
    	"set-countpoint" command name.
    	(OnBreakpointHandler::do_handle): If a breakpoint was set with the
    	generic "set-countpoint" command name, flag the Nemiver-side
    	breakpoint as a countpoint. We need to handle the marking of a bp
    	as a countpoint b/c countpoints are not native GDB objects. They
    	are Nemiver-only objects.
    	(GDBEngine::maybe_handle_countpoint): New fn.
    	(GDBEngine::on_stopped_signal): Use it. Continue if we stopped on
    	a countpoint.
    	(GDBEngine::append_breakpoints_to_cache): Do not loose
    	countpointness when updating our internal breakpoint cache with
    	GDB breakpoints.
    	* src/persp/dbgperspective/icons/countpoint-marker.png:
    	* src/persp/dbgperspective/icons/Makefile.am: Add
    	countpoint-marker.png to the build system.
    	* src/persp/dbgperspective/nmv-breakpoints-view.cc
    	(BreakpointsView::Priv::update_breakpoint): The "type" column
    	value for countpoints is not "countpoint".
    	* src/uicommon/nmv-source-editor.h (set_visual_breakpoint_at_line)
    	(set_visual_breakpoint_at_address): Add an is_countpoint flag.
    	* src/uicommon/nmv-source-editor.cc (SourceEditor::Priv::init):
    	Register a marker for countpoints.
    	(SourceEditor::set_visual_breakpoint_at_line)
    	(SourceEditor::set_visual_breakpoint_at_address): Support
    	countpoints.
    	* src/persp/dbgperspective/ui/setbreakpointdialog.ui: Add a
    	countpoint check button.
    	* src/persp/dbgperspective/nmv-set-breakpoint-dialog.h
    	(count_point): New accessor.
    	* src/persp/dbgperspective/nmv-set-breakpoint-dialog.cc
    	(SetBreakpointDialog::Priv::Priv): Load the countpoint check
    	button widget.
    	(SetBreakpointDialog::Priv::on_radiobutton_changed): Set the
    	countpoint check button widget insensitive in event mode.
    	(SetBreakpointDialog::count_point): New accessor.
    	* src/persp/dbgperspective/sqlscripts/sqlite/create-tables.sql:
    	Add an iscountpoint column to the breakpoints table. Bump the
    	schema version to 1.5 because of this change.
    	* src/persp/dbgperspective/nmv-sess-mgr.h
    	(ISessMgr::Breakpoint::is_countpoint): New property.
    	* src/persp/dbgperspective/nmv-sess-mgr.cc
    	(SessMgr::store_session): Require the 1.5 schema version.  Persist
    	countpoints that are in the session.
    	(SessMgr::load_session): Load countpoints that were persisted.
    	* src/persp/dbgperspective/nmv-dbg-perspective.h (set_breakpoint):
    	Add an is_count_point flag to the API.
    	* src/persp/dbgperspective/nmv-dbg-perspective.cc
    	(DBGPerspective::set_breakpoint)
    	(DBGPerspective::append_visual_breakpoint): Add an is_count_point
    	flag to the API and implement it.
    	(DBGPerspective::on_debugger_asm_signal3)
    	(DBGPerspective::apply_decorations_to_source)
    	(DBGPerspective::apply_decorations_to_asm): Pass countpointness to
    	append_visual_breakpoint.
    	(DBGPerspective::toggle_breakpoint)
    	(DBGPerspective::set_breakpoint_from_dialog): Pass countpointness
    	to set_breakpoint.
    	(DBGPerspective::record_and_save_session): Record countpoints into
    	the session.
    	(DBGPerspective::execute_session): Set countpoints back.
    	(DBGPerspective::set_breakpoint): Add a new overload that takes an
    	IDebugger:Breakpoint in parameter. Make it support countpoints
    	too. This was extracted from ...
    	(DBGPerspective::execute_program): ... here.
    	(DBGPerspective::append_breakpoint): Support countpoints.

 src/dbgengine/nmv-debugger-utils.cc                |    7 +
 src/dbgengine/nmv-debugger-utils.h                 |    2 +
 src/dbgengine/nmv-gdb-engine.cc                    |  129 ++++++++++++++--
 src/dbgengine/nmv-gdb-engine.h                     |    8 +-
 src/dbgengine/nmv-i-debugger.h                     |    9 +-
 src/persp/dbgperspective/icons/Makefile.am         |    1 +
 .../dbgperspective/icons/countpoint-marker.png     |  Bin 0 -> 241 bytes
 src/persp/dbgperspective/nmv-breakpoints-view.cc   |   21 ++-
 src/persp/dbgperspective/nmv-dbg-perspective.cc    |  167 +++++++++++++-------
 src/persp/dbgperspective/nmv-dbg-perspective.h     |    8 +-
 src/persp/dbgperspective/nmv-sess-mgr.cc           |   42 +++--
 src/persp/dbgperspective/nmv-sess-mgr.h            |   26 ++-
 .../dbgperspective/nmv-set-breakpoint-dialog.cc    |   22 +++
 .../dbgperspective/nmv-set-breakpoint-dialog.h     |    3 +
 .../sqlscripts/sqlite/create-tables.sql            |    5 +-
 src/persp/dbgperspective/ui/setbreakpointdialog.ui |   28 +++-
 src/uicommon/nmv-source-editor.cc                  |   17 ++-
 src/uicommon/nmv-source-editor.h                   |   12 +-
 18 files changed, 379 insertions(+), 128 deletions(-)
---
diff --git a/src/dbgengine/nmv-debugger-utils.cc b/src/dbgengine/nmv-debugger-utils.cc
index 5970a76..9d156c3 100644
--- a/src/dbgengine/nmv-debugger-utils.cc
+++ b/src/dbgengine/nmv-debugger-utils.cc
@@ -85,5 +85,12 @@ dump_variable_value (IDebugger::VariableSafePtr a_var,
     a_out_str = os.str ();
 }
 
+bool
+is_countpoint (const IDebugger::Breakpoint &a_breakpoint)
+{
+  return (a_breakpoint.type ()
+	  == IDebugger::Breakpoint::COUNTPOINT_TYPE);
+}
+
 NEMIVER_END_NAMESPACE (debugger_utils)
 NEMIVER_END_NAMESPACE (nemiver)
diff --git a/src/dbgengine/nmv-debugger-utils.h b/src/dbgengine/nmv-debugger-utils.h
index 125368c..dfe6f51 100644
--- a/src/dbgengine/nmv-debugger-utils.h
+++ b/src/dbgengine/nmv-debugger-utils.h
@@ -41,6 +41,8 @@ void dump_variable_value (IDebugger::VariableSafePtr a_var,
                           int a_indent_num,
                           std::string &a_out_str);
 
+bool is_countpoint (const IDebugger::Breakpoint &);
+
 NEMIVER_END_NAMESPACE (debugger_utils)
 NEMIVER_END_NAMESPACE (nemiver)
 
diff --git a/src/dbgengine/nmv-gdb-engine.cc b/src/dbgengine/nmv-gdb-engine.cc
index dfd4b7b..10fad81 100644
--- a/src/dbgengine/nmv-gdb-engine.cc
+++ b/src/dbgengine/nmv-gdb-engine.cc
@@ -1210,6 +1210,13 @@ struct OnBreakpointHandler: OutputHandler {
         bool has_breaks = false;
         //if breakpoint where set, put them in cache !
         if (has_breakpoints_set (a_in)) {
+            if (a_in.command ().name () == "set-countpoint") {
+                THROW_IF_FAIL (a_in.output ().result_record ().
+                               breakpoints ().size () == 1);
+                a_in.output ().result_record ().
+                    breakpoints ().begin ()->second.type
+                    (IDebugger::Breakpoint::COUNTPOINT_TYPE);
+            }
             m_engine->append_breakpoints_to_cache
             (a_in.output ().result_record ().breakpoints ());
             has_breaks = true;
@@ -1244,11 +1251,11 @@ struct OnBreakpointHandler: OutputHandler {
                            << tmp
                            << "', but that's not a well formed number dude.");
             }
-        } else if (has_breaks){
+        } else if (has_breaks) {
             LOG_DD ("firing IDebugger::breakpoint_set_signal()");
             m_engine->breakpoints_set_signal ().emit
-                            (a_in.output ().result_record ().breakpoints (),
-                             a_in.command ().cookie ());
+                (m_engine->get_cached_breakpoints (),
+                 a_in.command ().cookie ());
             m_engine->set_state (IDebugger::READY);
         } else {
             LOG_DD ("finally, no breakpoint was detected as set/deleted");
@@ -3255,6 +3262,28 @@ GDBEngine::on_got_target_info_signal (int a_pid, const UString &a_exe_path)
     NEMIVER_CATCH_NOX
 }
 
+/// If the given breakpoint is a countpoint, continue the execution of
+/// the inferior. This is a subroutine of GDBEngine::on_stopped_signal.
+/// \param a_reason the reason why the inferior stopped its execution.
+/// \param a_breakpoint_num the number of the breakpoint to consider.
+void
+GDBEngine::maybe_handle_countpoint (IDebugger::StopReason a_reason,
+                                    int a_breakpoint_num)
+{
+    if (a_reason != IDebugger::BREAKPOINT_HIT)
+        return;
+
+    map<int, IDebugger::Breakpoint>::const_iterator it, nil =
+        get_cached_breakpoints ().end ();       
+    it = get_cached_breakpoints ().find (a_breakpoint_num);
+    THROW_IF_FAIL (it != nil);
+
+    if (it->second.type () != IDebugger::Breakpoint::COUNTPOINT_TYPE)
+        return;
+
+    do_continue ("");
+}
+
 void
 GDBEngine::on_stopped_signal (IDebugger::StopReason a_reason,
                               bool a_has_frame,
@@ -3279,6 +3308,10 @@ GDBEngine::on_stopped_signal (IDebugger::StopReason a_reason,
 
     m_priv->is_attached = true;
 
+    // If we stopped on a breakpoint marked as a countpoint, let's
+    // continue the execution.
+    maybe_handle_countpoint (a_reason, a_bkpt_num);
+
     NEMIVER_CATCH_NOX
 }
 
@@ -3610,7 +3643,7 @@ void
 GDBEngine::set_breakpoint (const UString &a_path,
                            gint a_line_num,
                            const UString &a_condition,
-                           unsigned a_ignore_count,
+                           gint a_ignore_count,
                            const UString &a_cookie)
 {
     LOG_FUNCTION_SCOPE_NORMAL_DD;
@@ -3625,20 +3658,24 @@ GDBEngine::set_breakpoint (const UString &a_path,
         LOG_DD ("setting breakpoint without condition");
     }
 
-    break_cmd += " -i " + UString::from_int (a_ignore_count);
+    bool count_point = (a_ignore_count < 0);
+    if (!count_point)
+      break_cmd += " -i " + UString::from_int (a_ignore_count);
 
     if (!a_path.empty ()) {
         break_cmd += " " + a_path + ":";
     }
     break_cmd += UString::from_int (a_line_num);
-    queue_command (Command ("set-breakpoint", break_cmd, a_cookie));
+    string cmd_name = count_point ? "set-countpoint" : "set-breakpoint";
+    queue_command (Command (cmd_name,
+			    break_cmd, a_cookie));
 }
 
 
 void
 GDBEngine::set_breakpoint (const Address &a_address,
                            const UString &a_condition,
-                           unsigned a_ignore_count,
+                           gint a_ignore_count,
                            const UString &a_cookie)
 {
     LOG_FUNCTION_SCOPE_NORMAL_DD;
@@ -3652,11 +3689,13 @@ GDBEngine::set_breakpoint (const Address &a_address,
     } else {
         LOG_DD ("setting breakpoint without condition");
     }
-
-    break_cmd += " -i " + UString::from_int (a_ignore_count);
+    bool count_point = a_ignore_count < 0;
+    if (!count_point)
+      break_cmd += " -i " + UString::from_int (a_ignore_count);
     break_cmd += " *" + (const string&) a_address;
 
-    queue_command (Command ("set-breakpoint", break_cmd, a_cookie));
+    string cmd_name = count_point ? "set-countpoint" : "set-breakpoint";
+    queue_command (Command (cmd_name, break_cmd, a_cookie));
 }
 
 void
@@ -3758,7 +3797,7 @@ GDBEngine::set_watchpoint (const UString &a_expression,
 void
 GDBEngine::set_breakpoint (const UString &a_func_name,
                            const UString &a_condition,
-                           unsigned a_ignore_count,
+                           gint a_ignore_count,
                            const UString &a_cookie)
 {
     LOG_FUNCTION_SCOPE_NORMAL_DD;
@@ -3782,7 +3821,7 @@ GDBEngine::list_breakpoints (const UString &a_cookie)
 {
     LOG_FUNCTION_SCOPE_NORMAL_DD;
 
-    queue_command (Command ("list-breakpoint", "-break-list", a_cookie));
+    queue_command (Command ("list-breakpoints", "-break-list", a_cookie));
 }
 
 map<int, IDebugger::Breakpoint>&
@@ -3792,13 +3831,75 @@ GDBEngine::get_cached_breakpoints ()
     return m_priv->cached_breakpoints;
 }
 
+/// Append a set of breakpoints to our breakpoint cache.
+/// This function supports the countpoint feature. That is, as a
+/// countpoint is a concept not known to GDB, we have to mark an
+/// otherwise normal breakpoint [from GDB's standpoint] as a
+/// countpoint, in our cache. So whenever we see a breakpoint that we
+/// have previously marked as a countpoint in our cache, we make sure
+/// to not loose the countpointness.
+/// \param a_breaks the set of breakpoints to append to the cache.
 void
 GDBEngine::append_breakpoints_to_cache
                             (const map<int, IDebugger::Breakpoint> &a_breaks)
 {
-    map<int, IDebugger::Breakpoint>::const_iterator iter;
+    LOG_FUNCTION_SCOPE_NORMAL_DD;
+
+    typedef map<int, IDebugger::Breakpoint> BpMap;
+    typedef BpMap::iterator BpIt;
+    typedef BpMap::const_iterator ConstBpIt;
+
+    BpMap &bp_cache = m_priv->cached_breakpoints;
+    ConstBpIt iter;
+    BpIt cur, nil = bp_cache.end ();
+    bool preserve_count_point;
+
     for (iter = a_breaks.begin (); iter != a_breaks.end (); ++iter) {
-        m_priv->cached_breakpoints[iter->first] = iter->second;
+        preserve_count_point = false;
+        if (iter->second.type () == IDebugger::Breakpoint::COUNTPOINT_TYPE) {
+            LOG_DD ("breakpoint number "
+                    << iter->first
+                    << " is a count point");
+        } else {
+            LOG_DD ("breakpoint number "
+                    << iter->first
+                    << " is not a count point");
+        }
+        
+        // First, let's see if the breakpoint pointed to by iter is
+        // already in our cache.
+        cur = bp_cache.find (iter->first);
+        if (cur != nil) {
+            // So the breakpoint iter->second is already in the
+            // cache. If we flagged it as a countpoint, let's remember
+            // that so that we don't loose the countpointness of the
+            // breakpoint in the cache when we update its state with
+            // the content of iter->second.
+            if (cur->second.type () == IDebugger::Breakpoint::COUNTPOINT_TYPE)
+                preserve_count_point = true;
+        }
+
+        // So now is the cache updating time.
+
+        // If the breakpoint iter->second was already in the cache and
+        // was flagged as a countpoint, let's preserve that
+        // countpointness attribute.
+        if (cur != nil) {
+            cur->second = iter->second;
+            if (preserve_count_point) {
+                cur->second.type (IDebugger::Breakpoint::COUNTPOINT_TYPE);
+                LOG_DD ("propagated countpoinness to bp number " << cur->first);
+            }
+        } else {
+            // Its the first time we are adding this breakpoint to the
+            // cache. So its countpointness is going to be kept
+            // anyway.
+            std::pair<BpIt,bool> where = bp_cache.insert (*iter);
+            if (preserve_count_point) {
+                where.first->second.type (IDebugger::Breakpoint::COUNTPOINT_TYPE);
+                LOG_DD ("propagated countpoinness to bp number " << cur->first);
+            }
+        }
     }
 }
 
diff --git a/src/dbgengine/nmv-gdb-engine.h b/src/dbgengine/nmv-gdb-engine.h
index cd36ef1..fbc6582 100644
--- a/src/dbgengine/nmv-gdb-engine.h
+++ b/src/dbgengine/nmv-gdb-engine.h
@@ -224,6 +224,8 @@ public:
     //for internal use
     void init ();
 
+    void maybe_handle_countpoint (IDebugger::StopReason a_reason,
+				  int a_breakpoint_num);
     // to be called by client code
     void do_init (IConfMgrSafePtr a_conf_mgr);
 
@@ -325,17 +327,17 @@ public:
     void set_breakpoint (const UString &a_path,
                          gint a_line_num,
                          const UString &a_condition,
-                         unsigned a_ignore_count,
+                         gint a_ignore_count,
                          const UString &a_cookie) ;
 
     void set_breakpoint (const UString &a_func_name,
                          const UString &a_condition,
-                         unsigned a_ignore_count,
+                         gint a_ignore_count,
                          const UString &a_cookie);
 
     void set_breakpoint (const Address &a_address,
                          const UString &a_condition,
-                         unsigned a_ignore_count,
+                         gint a_ignore_count,
                          const UString &a_cookie);
 
     void enable_breakpoint (gint a_break_num,
diff --git a/src/dbgengine/nmv-i-debugger.h b/src/dbgengine/nmv-i-debugger.h
index 101573c..7c9b87a 100644
--- a/src/dbgengine/nmv-i-debugger.h
+++ b/src/dbgengine/nmv-i-debugger.h
@@ -90,7 +90,8 @@ public:
         enum Type {
             UNDEFINED_TYPE = 0,
             STANDARD_BREAKPOINT_TYPE,
-            WATCHPOINT_TYPE
+            WATCHPOINT_TYPE,
+            COUNTPOINT_TYPE
         };
 
     private:
@@ -1077,17 +1078,17 @@ public:
     virtual void set_breakpoint (const UString &a_path,
                                  gint a_line_num,
                                  const UString &a_condition= "",
-                                 unsigned a_ignore_count = 0,
+                                 gint a_ignore_count = 0,
                                  const UString &a_cookie = "") = 0;
 
     virtual void set_breakpoint (const UString &a_func_name,
                                  const UString &a_condition = "",
-                                 unsigned a_ignore_count = 0,
+                                 gint a_ignore_count = 0,
                                  const UString &a_cookie = "") = 0;
 
     virtual void set_breakpoint (const Address &a_address,
                                  const UString &a_condition = "",
-                                 unsigned a_ignore_count = 0,
+                                 gint a_ignore_count = 0,
                                  const UString &a_cookie = "") = 0;
 
     virtual void enable_breakpoint (gint a_break_num,
diff --git a/src/persp/dbgperspective/icons/Makefile.am b/src/persp/dbgperspective/icons/Makefile.am
index b610914..2614af8 100644
--- a/src/persp/dbgperspective/icons/Makefile.am
+++ b/src/persp/dbgperspective/icons/Makefile.am
@@ -3,6 +3,7 @@ iconsfiles = \
 set-breakpoint.xpm \
 breakpoint-marker.png \
 breakpoint-disabled-marker.png \
+countpoint-marker.png \
 line-pointer.png \
 run-to-cursor.xpm \
 step-into.xpm \
diff --git a/src/persp/dbgperspective/icons/countpoint-marker.png b/src/persp/dbgperspective/icons/countpoint-marker.png
new file mode 100644
index 0000000..3700e55
Binary files /dev/null and b/src/persp/dbgperspective/icons/countpoint-marker.png differ
diff --git a/src/persp/dbgperspective/nmv-breakpoints-view.cc b/src/persp/dbgperspective/nmv-breakpoints-view.cc
index 4982498..879b40e 100644
--- a/src/persp/dbgperspective/nmv-breakpoints-view.cc
+++ b/src/persp/dbgperspective/nmv-breakpoints-view.cc
@@ -290,15 +290,18 @@ public:
 
         (*a_iter)[get_bp_cols ().is_standard] = false;
         switch (a_breakpoint.type ()) {
-            case IDebugger::Breakpoint::STANDARD_BREAKPOINT_TYPE:
-                (*a_iter)[get_bp_cols ().type] = _("breakpoint");
-                (*a_iter)[get_bp_cols ().is_standard] = true;
-                break;
-            case IDebugger::Breakpoint::WATCHPOINT_TYPE:
-                (*a_iter)[get_bp_cols ().type] = _("watchtpoint");
-                break;
-            default:
-                (*a_iter)[get_bp_cols ().type] = _("unknown");
+	case IDebugger::Breakpoint::STANDARD_BREAKPOINT_TYPE:
+	  (*a_iter)[get_bp_cols ().type] = _("breakpoint");
+	  (*a_iter)[get_bp_cols ().is_standard] = true;
+	  break;
+	case IDebugger::Breakpoint::WATCHPOINT_TYPE:
+	  (*a_iter)[get_bp_cols ().type] = _("watchpoint");
+	  break;
+	case IDebugger::Breakpoint::COUNTPOINT_TYPE:
+	  (*a_iter)[get_bp_cols ().type] = _("countpoint");
+	  break;
+	default:
+	  (*a_iter)[get_bp_cols ().type] = _("unknown");
         }
         (*a_iter)[get_bp_cols ().hits] = a_breakpoint.nb_times_hit ();
     }
diff --git a/src/persp/dbgperspective/nmv-dbg-perspective.cc b/src/persp/dbgperspective/nmv-dbg-perspective.cc
index bd02707..384bde1 100644
--- a/src/persp/dbgperspective/nmv-dbg-perspective.cc
+++ b/src/persp/dbgperspective/nmv-dbg-perspective.cc
@@ -98,6 +98,7 @@
 #include "nmv-memory-view.h"
 #endif // WITH_MEMORYVIEW
 #include "nmv-watchpoint-dialog.h"
+#include "nmv-debugger-utils.h"
 
 using namespace std;
 using namespace nemiver::common;
@@ -609,10 +610,14 @@ public:
     void set_breakpoint ();
     void set_breakpoint (const UString &a_file,
                          int a_line,
-                         const UString &a_cond);
+                         const UString &a_cond,
+                         bool a_is_count_point);
     void set_breakpoint (const UString &a_func_name,
-                         const UString &a_cond);
-    void set_breakpoint (const Address &a_address);
+                         const UString &a_cond,
+                         bool a_is_count_point);
+    void set_breakpoint (const Address &a_address,
+                         bool a_is_count_point);
+    void set_breakpoint (const IDebugger::Breakpoint &a_breakpoint);
     void append_breakpoint (int a_bp_num,
                             const IDebugger::Breakpoint &a_breakpoint);
     void append_breakpoints
@@ -669,10 +674,12 @@ public:
                                   UString& a_selected_file_path);
     bool append_visual_breakpoint (SourceEditor *editor,
                                    int linenum,
-                                   bool enabled = true);
+                                   bool is_countpoint,
+                                   bool enabled);
     bool append_visual_breakpoint (SourceEditor *editor,
                                    const Address &address,
-                                   bool enabled = true);
+                                   bool is_countpoint,
+                                   bool enabled);
     void delete_visual_breakpoint (const UString &a_file_name, int a_linenum);
     void delete_visual_breakpoint (int a_breaknum);
     void choose_function_overload
@@ -2726,6 +2733,7 @@ DBGPerspective::on_debugger_asm_signal3
     switch_to_asm (a_info, a_instrs, a_editor,
                    /*a_approximate_where=*/true);
     append_visual_breakpoint (a_editor, a_bp.address (),
+                              debugger_utils::is_countpoint (a_bp),
                               a_bp.line ());
 
     NEMIVER_CATCH;
@@ -5164,14 +5172,18 @@ DBGPerspective::record_and_save_session (ISessMgr::Session &a_session)
     for (break_iter = m_priv->breakpoints.begin ();
          break_iter != m_priv->breakpoints.end ();
          ++break_iter) {
-        if (break_iter->second.type ()
-            == IDebugger::Breakpoint::STANDARD_BREAKPOINT_TYPE) {
+        if ((break_iter->second.type ()
+             == IDebugger::Breakpoint::STANDARD_BREAKPOINT_TYPE)
+            || (break_iter->second.type ()
+             == IDebugger::Breakpoint::COUNTPOINT_TYPE)) {
             ISessMgr::Breakpoint bp (break_iter->second.file_name (),
                                      break_iter->second.file_full_name (),
                                      break_iter->second.line (),
                                      break_iter->second.enabled (),
                                      break_iter->second.condition (),
-                                     break_iter->second.ignore_count ());
+                                     break_iter->second.ignore_count (),
+                                     debugger_utils::is_countpoint
+                                     (break_iter->second));
             a_session.breakpoints ().push_back (bp);
             LOG_DD ("Regular breakpoint scheduled to be stored");
         } else if (break_iter->second.type ()
@@ -5830,6 +5842,12 @@ DBGPerspective::execute_session (ISessMgr::Session &a_session)
         breakpoint.enabled (it->enabled ());
         breakpoint.condition (it->condition ());
         breakpoint.ignore_count (it->ignore_count ());
+        if (it->is_countpoint ()) {
+            breakpoint.type (IDebugger::Breakpoint::COUNTPOINT_TYPE);
+            LOG_DD ("breakpoint "
+                    << it->file_name () << ":" << it->line_number ()
+                    << " is a countpoint");
+        }
         breakpoints.push_back (breakpoint);
     }
 
@@ -6055,35 +6073,6 @@ DBGPerspective::execute_program
     // set environment variables of the inferior
     dbg_engine->add_env_variables (a_env);
 
-// If the breakpoint was marked as 'disabled' in the session DB, we
-// have to set it and immediately disable it.  We need to pass along
-// some additional information in the 'cookie' to determine which
-// breakpoint needs to be disabling after it is set.
-// This macro helps us to do that.
-#define SET_BREAKPOINT(BP) __extension__                                \
-        ({                                                              \
-            UString file_name = (BP).file_full_name ().empty ()         \
-                ? (BP).file_name ()                                     \
-                : (BP).file_full_name ();                               \
-            UString cookie = (BP).enabled ()                            \
-                ? ""                                                    \
-                : "initially-disabled#" + file_name                     \
-                + "#" + UString::from_int ((BP).line ());               \
-            if ((BP).type ()                                            \
-                == IDebugger::Breakpoint::STANDARD_BREAKPOINT_TYPE      \
-                && !file_name.empty ())                                 \
-                dbg_engine->set_breakpoint (file_name,                  \
-                                            (BP).line (),               \
-                                            (BP).condition (),          \
-                                            (BP).ignore_count (),       \
-                                            cookie);                    \
-            else if ((BP).type ()                                       \
-                     == IDebugger::Breakpoint::WATCHPOINT_TYPE)         \
-                dbg_engine->set_watchpoint ((BP).expression (),         \
-                                            (BP).is_write_watchpoint (), \
-                                            (BP).is_read_watchpoint ()); \
-        })
-
     // If this is a new program we are debugging,
     // set a breakpoint in 'main' by default.
     if (a_breaks.empty ()) {
@@ -6092,7 +6081,7 @@ DBGPerspective::execute_program
             for (it = m_priv->breakpoints.begin ();
                  it != m_priv->breakpoints.end ();
                  ++it) {
-                SET_BREAKPOINT (it->second);
+                set_breakpoint (it->second);
             }
         } else {
             dbg_engine->set_breakpoint ("main");
@@ -6100,7 +6089,7 @@ DBGPerspective::execute_program
     } else {
         vector<IDebugger::Breakpoint>::const_iterator it;
         for (it = a_breaks.begin (); it != a_breaks.end (); ++it) {
-            SET_BREAKPOINT (*it);
+            set_breakpoint (*it);
         }
     }
 
@@ -6383,19 +6372,23 @@ DBGPerspective::set_breakpoint ()
     gint current_line =
         source_editor->source_view ().get_source_buffer ()->get_insert
             ()->get_iter ().get_line () + 1;
-    set_breakpoint (path, current_line, "");
+    set_breakpoint (path, current_line,
+                    /*condition=*/"",
+                    /*is_countpoint*/false);
 }
 
 void
 DBGPerspective::set_breakpoint (const UString &a_file_path,
                                 int a_line,
-                                const UString &a_condition)
+                                const UString &a_condition,
+                                bool a_is_count_point)
 {
     LOG_DD ("set bkpoint request for " << a_file_path << ":" << a_line
             << " condition: '" << a_condition << "'");
         // only try to set the breakpoint if it's a reasonable value
         if (a_line && a_line != INT_MAX && a_line != INT_MIN) {
-            debugger ()->set_breakpoint (a_file_path, a_line, a_condition);
+            debugger ()->set_breakpoint (a_file_path, a_line, a_condition,
+                                         a_is_count_point ? -1 : 0);
         } else {
             LOG_ERROR ("invalid line number: " << a_line);
             UString msg;
@@ -6406,16 +6399,57 @@ DBGPerspective::set_breakpoint (const UString &a_file_path,
 
 void
 DBGPerspective::set_breakpoint (const UString &a_func_name,
-                                const UString &a_condition)
+                                const UString &a_condition,
+                                bool a_is_count_point)
 {
     LOG_DD ("set bkpoint request in func" << a_func_name);
-    debugger ()->set_breakpoint (a_func_name, a_condition);
+    debugger ()->set_breakpoint (a_func_name, a_condition,
+                                 a_is_count_point ? -1 : 0);
 }
 
 void
-DBGPerspective::set_breakpoint (const Address &a_address)
+DBGPerspective::set_breakpoint (const Address &a_address,
+                                bool a_is_count_point)
 {
-    debugger ()->set_breakpoint (a_address);
+    debugger ()->set_breakpoint (a_address, "",
+                                 a_is_count_point ? -1 : 0);
+}
+
+void
+DBGPerspective::set_breakpoint (const IDebugger::Breakpoint &a_breakpoint)
+{
+    UString file_name = a_breakpoint.file_full_name ().empty ()
+        ? a_breakpoint.file_name ()
+        : a_breakpoint.file_full_name ();
+
+    // If the breakpoint was marked as 'disabled' in the session DB,
+    // we have to set it and immediately disable it.  We need to pass
+    // along some additional information in the 'cookie' to determine
+    // which breakpoint needs to be disabling after it is set.
+    UString cookie = a_breakpoint.enabled ()
+        ? ""
+        : "initially-disabled#" + file_name
+        + "#" + UString::from_int (a_breakpoint.line ());
+
+    // Now set the breakpoint proper.
+    if (a_breakpoint.type () == IDebugger::Breakpoint::STANDARD_BREAKPOINT_TYPE
+        || a_breakpoint.type () == IDebugger::Breakpoint::COUNTPOINT_TYPE) {
+        int ignore_count =
+            debugger_utils::is_countpoint (a_breakpoint)
+            ? -1
+            : a_breakpoint.ignore_count ();
+
+        if (!file_name.empty ())
+            debugger ()->set_breakpoint (file_name,
+                                         a_breakpoint.line (),
+                                         a_breakpoint.condition (),
+                                         ignore_count, cookie);
+    } else if (a_breakpoint.type ()
+               == IDebugger::Breakpoint::WATCHPOINT_TYPE) {
+        debugger ()->set_watchpoint (a_breakpoint.expression (),
+                                     a_breakpoint.is_write_watchpoint (),
+                                     a_breakpoint.is_read_watchpoint ());
+    }
 }
 
 void
@@ -6429,7 +6463,8 @@ DBGPerspective::append_breakpoint (int a_bp_num,
     IDebugger::Breakpoint::Type type = a_breakpoint.type ();
     SourceEditor *editor = 0;
 
-    if (type == IDebugger::Breakpoint::STANDARD_BREAKPOINT_TYPE
+    if ((type == IDebugger::Breakpoint::STANDARD_BREAKPOINT_TYPE
+         || type == IDebugger::Breakpoint::COUNTPOINT_TYPE)
         && file_path.empty ()) {
         file_path = a_breakpoint.file_name ();
     }
@@ -6439,7 +6474,8 @@ DBGPerspective::append_breakpoint (int a_bp_num,
 
     // We don't know how to graphically represent non-standard
     // breakpoints (e.g watchpoints) at this moment.
-    if (type != IDebugger::Breakpoint::STANDARD_BREAKPOINT_TYPE)
+    if (type != IDebugger::Breakpoint::STANDARD_BREAKPOINT_TYPE
+        && type != IDebugger::Breakpoint::COUNTPOINT_TYPE)
         return;
 
     editor = get_or_append_source_editor_from_path (file_path);
@@ -6451,10 +6487,14 @@ DBGPerspective::append_breakpoint (int a_bp_num,
         switch (type) {
             case SourceEditor::BUFFER_TYPE_SOURCE:
                 append_visual_breakpoint (editor, a_breakpoint.line (),
+                                          debugger_utils::is_countpoint
+                                          (a_breakpoint),
                                           a_breakpoint.enabled ());
                 break;
             case SourceEditor::BUFFER_TYPE_ASSEMBLY:
                 append_visual_breakpoint (editor, a_breakpoint.address (),
+                                          debugger_utils::is_countpoint
+                                          (a_breakpoint),
                                           a_breakpoint.enabled ());
                 break;
             case SourceEditor::BUFFER_TYPE_UNDEFINED:
@@ -6600,25 +6640,31 @@ DBGPerspective::ask_user_to_select_file (const UString &a_file_name,
 bool
 DBGPerspective::append_visual_breakpoint (SourceEditor *a_editor,
                                           int a_linenum,
+                                          bool a_is_countpoint,
                                           bool a_enabled)
 {
     LOG_FUNCTION_SCOPE_NORMAL_DD
 
     if (a_editor == 0)
         return false;
-    return a_editor->set_visual_breakpoint_at_line (a_linenum, a_enabled);
+    return a_editor->set_visual_breakpoint_at_line (a_linenum,
+                                                    a_is_countpoint,
+                                                    a_enabled);
 }
 
 bool
 DBGPerspective::append_visual_breakpoint (SourceEditor *a_editor,
                                           const Address &a_address,
+                                          bool a_is_countpoint,
                                           bool a_enabled)
 {
     LOG_FUNCTION_SCOPE_NORMAL_DD
 
     if (a_editor == 0)
         return false;
-    return a_editor->set_visual_breakpoint_at_address (a_address, a_enabled);
+    return a_editor->set_visual_breakpoint_at_address (a_address,
+                                                       a_is_countpoint,
+                                                       a_enabled);
 }
 
 void
@@ -6756,6 +6802,8 @@ DBGPerspective::apply_decorations_to_source (SourceEditor *a_editor,
         if (a_editor->get_path () == it->second.file_full_name ()) {
             append_visual_breakpoint (a_editor,
                                       it->second.line (),
+                                      debugger_utils::is_countpoint
+                                      (it->second),
                                       it->second.enabled ());
         }
     }
@@ -6800,6 +6848,8 @@ DBGPerspective::apply_decorations_to_asm (SourceEditor *a_editor,
         if (a_editor->get_path () == it->second.file_full_name ()) {
             Address addr = it->second.address ();
             if (!append_visual_breakpoint (a_editor, addr,
+                                           debugger_utils::is_countpoint
+                                           (it->second),
                                            it->second.enabled ())) {
                 LOG_DD ("Could'nt find line for address: "
                         << addr.to_string ()
@@ -6897,7 +6947,9 @@ DBGPerspective::toggle_breakpoint (const UString &a_file_path,
         delete_breakpoint (a_file_path, a_line_num);
     } else {
         LOG_DD ("breakpoint no set yet, set it!");
-        set_breakpoint (a_file_path, a_line_num, "");
+        set_breakpoint (a_file_path, a_line_num,
+                        /*condition=*/"",
+                        /*is_count_point=*/false);
     }
 }
 
@@ -6908,7 +6960,7 @@ DBGPerspective::toggle_breakpoint (const Address &a_address)
     if (is_breakpoint_set_at_address (a_address)) {
         delete_breakpoint (a_address);
     } else {
-        set_breakpoint (a_address);
+        set_breakpoint (a_address, /*is_count_point=*/false);
     }
 }
 
@@ -6931,6 +6983,8 @@ DBGPerspective::toggle_breakpoint ()
 void
 DBGPerspective::set_breakpoint_from_dialog (SetBreakpointDialog &a_dialog)
 {
+    bool is_count_point = a_dialog.count_point ();
+
     switch (a_dialog.mode ()) {
         case SetBreakpointDialog::MODE_SOURCE_LOCATION:
             {
@@ -6950,7 +7004,9 @@ DBGPerspective::set_breakpoint_from_dialog (SetBreakpointDialog &a_dialog)
                 int line = a_dialog.line_number ();
                 LOG_DD ("setting breakpoint in file "
                         << filename << " at line " << line);
-                set_breakpoint (filename, line, a_dialog.condition ());
+                set_breakpoint (filename, line,
+                                a_dialog.condition (),
+                                is_count_point);
                 break;
             }
 
@@ -6959,7 +7015,8 @@ DBGPerspective::set_breakpoint_from_dialog (SetBreakpointDialog &a_dialog)
                 UString function = a_dialog.function ();
                 THROW_IF_FAIL (function != "");
                 LOG_DD ("setting breakpoint at function: " << function);
-                set_breakpoint (function, a_dialog.condition ());
+                set_breakpoint (function, a_dialog.condition (),
+                                is_count_point);
                 break;
             }
 
@@ -6969,7 +7026,7 @@ DBGPerspective::set_breakpoint_from_dialog (SetBreakpointDialog &a_dialog)
                 if (!address.empty ()) {
                     LOG_DD ("setting breakpoint at address: "
                             << address);
-                    set_breakpoint (address);
+                    set_breakpoint (address, is_count_point);
                 }
                 break;
             }
diff --git a/src/persp/dbgperspective/nmv-dbg-perspective.h b/src/persp/dbgperspective/nmv-dbg-perspective.h
index 72d3258..68355b6 100644
--- a/src/persp/dbgperspective/nmv-dbg-perspective.h
+++ b/src/persp/dbgperspective/nmv-dbg-perspective.h
@@ -121,10 +121,14 @@ public:
 
     virtual void set_breakpoint (const UString &a_file,
                                  int a_line,
-                                 const UString &a_condition="") = 0;
+                                 const UString &a_condition,
+				 bool a_is_count_point) = 0;
 
     virtual void set_breakpoint (const UString &a_func_name,
-                                 const UString &a_condition="") = 0;
+                                 const UString &a_condition,
+				 bool a_is_count_point) = 0;
+
+    virtual void set_breakpoint (const IDebugger::Breakpoint &a_breakpoint) = 0;
 
     virtual void append_breakpoints
             (const map<int, IDebugger::Breakpoint> &a_breaks) = 0;
diff --git a/src/persp/dbgperspective/nmv-sess-mgr.cc b/src/persp/dbgperspective/nmv-sess-mgr.cc
index 6391e33..b2c44a2 100644
--- a/src/persp/dbgperspective/nmv-sess-mgr.cc
+++ b/src/persp/dbgperspective/nmv-sess-mgr.cc
@@ -43,7 +43,7 @@ using nemiver::common::ConnectionManager;
 using nemiver::common::Transaction;
 using nemiver::common::SQLStatement;
 
-static const char *REQUIRED_DB_SCHEMA_VERSION = "1.4";
+static const char *REQUIRED_DB_SCHEMA_VERSION = "1.5";
 static const char *DB_FILE_NAME = "nemivercommon.db";
 
 NEMIVER_BEGIN_NAMESPACE (nemiver)
@@ -340,16 +340,16 @@ SessMgr::store_session (Session &a_session,
         UString condition = break_iter->condition ();
         condition.chomp ();
         query = "insert into breakpoints values(NULL, "
-                + UString::from_int (a_session.session_id ()) + ", '"
-                + SQLStatement::escape_string
-                    (break_iter->file_name ()) + "', '"
-                + SQLStatement::escape_string
-                    (break_iter->file_full_name ()) + "', "
-                + UString::from_int (break_iter->line_number ()) + ", "
-                + UString::from_int (break_iter->enabled ()) + ", "
-                + "'" + SQLStatement::escape_string (condition) + "'" + ", "
-                + UString::from_int (break_iter->ignore_count ())
-                + ")";
+	  + UString::from_int (a_session.session_id ()) + ", '"
+	  + SQLStatement::escape_string (break_iter->file_name ()) + "', '"
+	  + SQLStatement::escape_string
+	  (break_iter->file_full_name ()) + "', "
+	  + UString::from_int (break_iter->line_number ()) + ", "
+	  + UString::from_int (break_iter->enabled ()) + ", "
+	  + "'" + SQLStatement::escape_string (condition) + "'" + ", "
+	  + UString::from_int (break_iter->ignore_count ()) + ", "
+	  + UString::from_int (break_iter->is_countpoint ())
+	  + ")";
         LOG_DD ("query: " << query);
         THROW_IF_FAIL
                 (trans.get ().get_connection ().execute_statement (query));
@@ -477,15 +477,17 @@ SessMgr::load_session (Session &a_session,
 
     // load the breakpoints
     query = "select breakpoints.filename, breakpoints.filefullname, "
-            "breakpoints.linenumber, breakpoints.enabled, "
-            "breakpoints.condition, breakpoints.ignorecount from "
-            "breakpoints where breakpoints.sessionid = "
-            + UString::from_int (session.session_id ());
+      "breakpoints.linenumber, breakpoints.enabled, "
+      "breakpoints.condition, breakpoints.ignorecount,"
+      "breakpoints.iscountpoint from "
+      "breakpoints where breakpoints.sessionid = "
+      + UString::from_int (session.session_id ());
+
     LOG_DD ("query: " << query);
     THROW_IF_FAIL (trans.get ().get_connection ().execute_statement (query));
     while (trans.get ().get_connection ().read_next_row ()) {
         UString filename, filefullname, linenumber,
-                enabled, condition, ignorecount;
+	  enabled, condition, ignorecount, is_countpoint;
         THROW_IF_FAIL (trans.get ().get_connection ().get_column_content
                                                             (0, filename));
         THROW_IF_FAIL (trans.get ().get_connection ().get_column_content
@@ -499,17 +501,21 @@ SessMgr::load_session (Session &a_session,
         condition.chomp ();
         THROW_IF_FAIL (trans.get ().get_connection ().get_column_content
                                                             (5, ignorecount));
+	THROW_IF_FAIL (trans.get ().get_connection ().get_column_content
+                                                            (6, is_countpoint));
         LOG_DD ("filename, filefullname, linenumber, enabled, "
                 "condition, ignorecount:\n"
                 << filename << "," << filefullname << ","
                 << linenumber << "," << enabled << ","
-                << condition<< "," << ignorecount);
+                << condition << "," << ignorecount
+		<< is_countpoint);
         session.breakpoints ().push_back (SessMgr::Breakpoint (filename,
                                                                filefullname,
                                                                linenumber,
                                                                enabled,
                                                                condition,
-                                                               ignorecount));
+                                                               ignorecount,
+							       is_countpoint));
     }
 
     // load the watchpoints
diff --git a/src/persp/dbgperspective/nmv-sess-mgr.h b/src/persp/dbgperspective/nmv-sess-mgr.h
index 144ec16..4a73b6b 100644
--- a/src/persp/dbgperspective/nmv-sess-mgr.h
+++ b/src/persp/dbgperspective/nmv-sess-mgr.h
@@ -62,6 +62,7 @@ public:
         bool m_enabled;
         UString m_condition;
         int m_ignore_count;
+	bool m_is_countpoint;
 
     public:
         Breakpoint (const UString &a_file_name,
@@ -69,13 +70,15 @@ public:
                     const UString &a_line_number,
                     const UString &a_enabled,
                     const UString &a_condition,
-                    const UString &a_ignore_count) :
-            m_file_name (a_file_name),
+                    const UString &a_ignore_count,
+                    const UString &a_is_countpoint) :
+	m_file_name (a_file_name),
             m_file_full_name (a_file_full_name),
             m_line_number (atoi (a_line_number.c_str ())),
             m_enabled (atoi (a_enabled.c_str ())),
             m_condition (a_condition),
-            m_ignore_count (atoi (a_ignore_count.c_str ()))
+            m_ignore_count (atoi (a_ignore_count.c_str ())),
+            m_is_countpoint (atoi (a_is_countpoint.c_str ()))
         {}
 
         Breakpoint (const UString &a_file_name,
@@ -83,18 +86,22 @@ public:
                     int a_line_number,
                     bool a_enabled,
                     const UString &a_condition,
-                    unsigned a_ignore_count) :
-            m_file_name (a_file_name),
+                    unsigned a_ignore_count,
+		    bool a_is_countpoint) :
+	m_file_name (a_file_name),
             m_file_full_name (a_file_full_name),
             m_line_number (a_line_number),
             m_enabled (a_enabled),
             m_condition (a_condition),
-            m_ignore_count (a_ignore_count)
+            m_ignore_count (a_ignore_count),
+            m_is_countpoint (a_is_countpoint)
         {}
 
         Breakpoint () :
-            m_line_number (0),
-            m_ignore_count (0)
+        m_line_number (0),
+            m_enabled (true),
+            m_ignore_count (0),            
+            m_is_countpoint (false)
         {}
 
         const UString& file_name () const {return m_file_name;}
@@ -114,6 +121,9 @@ public:
 
         int ignore_count () const {return m_ignore_count;}
         void ignore_count (int a_c) {m_ignore_count = a_c;}
+
+        bool is_countpoint () const {return m_is_countpoint;}
+        void is_countpoint (bool a) {m_is_countpoint = a;}
     };
 
     class WatchPoint {
diff --git a/src/persp/dbgperspective/nmv-set-breakpoint-dialog.cc b/src/persp/dbgperspective/nmv-set-breakpoint-dialog.cc
index 82d0927..e8017d6 100644
--- a/src/persp/dbgperspective/nmv-set-breakpoint-dialog.cc
+++ b/src/persp/dbgperspective/nmv-set-breakpoint-dialog.cc
@@ -66,6 +66,7 @@ public:
     Gtk::RadioButton *radio_function_name;
     Gtk::RadioButton *radio_binary_location;
     Gtk::RadioButton *radio_event;
+    Gtk::CheckButton *check_countpoint;
     Gtk::Button *okbutton;
 
 public:
@@ -80,6 +81,7 @@ public:
         radio_function_name (0),
         radio_binary_location (0),
         radio_event (0),
+        check_countpoint (0),
         okbutton (0)
     {
         a_dialog.set_default_response (Gtk::RESPONSE_OK);
@@ -176,6 +178,10 @@ public:
         radio_event->signal_clicked ().connect (sigc::mem_fun
                 (*this, &Priv::on_radiobutton_changed));
 
+        check_countpoint =
+            ui_utils::get_widget_from_gtkbuilder<Gtk::CheckButton>
+            (a_gtkbuilder, "countpointcheck");
+
         // set the 'function name' mode active by default
         mode (MODE_FUNCTION_NAME);
         // hack to ensure that the correct text entry fields
@@ -285,6 +291,7 @@ public:
         entry_address->set_sensitive (a_mode == MODE_BINARY_ADDRESS);
         combo_event->set_sensitive (a_mode == MODE_EVENT);
         entry_condition->set_sensitive (a_mode != MODE_EVENT);
+        check_countpoint->set_sensitive (a_mode != MODE_EVENT);
         update_ok_button_sensitivity ();
         NEMIVER_CATCH
     }
@@ -480,6 +487,21 @@ SetBreakpointDialog::condition (const UString &a_cond)
     m_priv->entry_condition->set_text (a_cond);
 }
 
+bool
+SetBreakpointDialog::count_point () const
+{
+    THROW_IF_FAIL (m_priv);
+    THROW_IF_FAIL (m_priv->check_countpoint);
+    return m_priv->check_countpoint->get_active ();
+}
+
+void
+SetBreakpointDialog::count_point (bool a_flag)
+{
+    THROW_IF_FAIL (m_priv);
+    THROW_IF_FAIL (m_priv->check_countpoint);
+    m_priv->check_countpoint->set_active (a_flag);
+}
 
 SetBreakpointDialog::Mode
 SetBreakpointDialog::mode () const
diff --git a/src/persp/dbgperspective/nmv-set-breakpoint-dialog.h b/src/persp/dbgperspective/nmv-set-breakpoint-dialog.h
index dec234a..ddc641f 100644
--- a/src/persp/dbgperspective/nmv-set-breakpoint-dialog.h
+++ b/src/persp/dbgperspective/nmv-set-breakpoint-dialog.h
@@ -75,6 +75,9 @@ public:
     UString condition () const;
     void condition (const UString &a_cond);
 
+    bool count_point () const;
+    void count_point (bool a_flag);
+
     Mode mode () const;
     void mode (Mode);
 
diff --git a/src/persp/dbgperspective/sqlscripts/sqlite/create-tables.sql b/src/persp/dbgperspective/sqlscripts/sqlite/create-tables.sql
index cf530bb..1340cbc 100644
--- a/src/persp/dbgperspective/sqlscripts/sqlite/create-tables.sql
+++ b/src/persp/dbgperspective/sqlscripts/sqlite/create-tables.sql
@@ -1,6 +1,6 @@
 create table schemainfo (version text not null) ;
 
-insert into schemainfo (version) values ('1.4') ;
+insert into schemainfo (version) values ('1.5') ;
 
 create table sessions (id integer primary key) ;
 
@@ -21,7 +21,8 @@ create table breakpoints (id integer primary key,
                           linenumber integer,
                           enabled integer,
                           condition text,
-                          ignorecount integer) ;
+                          ignorecount integer,
+			  iscountpoint integer) ;
 
 create table watchpoints (id integer primary key,
                           sessionid integer,
diff --git a/src/persp/dbgperspective/ui/setbreakpointdialog.ui b/src/persp/dbgperspective/ui/setbreakpointdialog.ui
index 9065f7c..bf5510b 100644
--- a/src/persp/dbgperspective/ui/setbreakpointdialog.ui
+++ b/src/persp/dbgperspective/ui/setbreakpointdialog.ui
@@ -39,7 +39,7 @@
                 <child>
                   <object class="GtkTable" id="table4">
                     <property name="visible">True</property>
-                    <property name="n_rows">10</property>
+                    <property name="n_rows">11</property>
                     <property name="n_columns">2</property>
                     <property name="column_spacing">6</property>
                     <property name="row_spacing">6</property>
@@ -91,13 +91,13 @@
                     <child>
                       <object class="GtkLabel" id="label8">
                         <property name="visible">True</property>
-                        <property name="xalign">1</property>
+                        <property name="xalign">0</property>
                         <property name="label" translatable="yes">Condition:</property>
                         <property name="mnemonic_widget">conditionentry</property>
                       </object>
                       <packing>
-                        <property name="top_attach">9</property>
-                        <property name="bottom_attach">10</property>
+                        <property name="top_attach">10</property>
+                        <property name="bottom_attach">11</property>
                         <property name="x_options">GTK_FILL</property>
                         <property name="y_options"></property>
                       </packing>
@@ -111,8 +111,8 @@
                       <packing>
                         <property name="left_attach">1</property>
                         <property name="right_attach">2</property>
-                        <property name="top_attach">9</property>
-                        <property name="bottom_attach">10</property>
+                        <property name="top_attach">10</property>
+                        <property name="bottom_attach">11</property>
                         <property name="y_options"></property>
                       </packing>
                     </child>
@@ -264,6 +264,22 @@
                       </packing>
                     </child>
                     <child>
+                      <object class="GtkCheckButton" id="countpointcheck">
+                        <property name="label" translatable="yes">Set as Countpoint</property>
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="receives_default">False</property>
+                        <property name="draw_indicator">True</property>
+                      </object>
+                      <packing>
+                        <property name="top_attach">9</property>
+                        <property name="bottom_attach">10</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <placeholder/>
+                    </child>
+                    <child>
                       <placeholder/>
                     </child>
                     <child>
diff --git a/src/uicommon/nmv-source-editor.cc b/src/uicommon/nmv-source-editor.cc
index 60c6e95..347f0d3 100644
--- a/src/uicommon/nmv-source-editor.cc
+++ b/src/uicommon/nmv-source-editor.cc
@@ -64,6 +64,7 @@ NEMIVER_BEGIN_NAMESPACE (nemiver)
 
 const char* BREAKPOINT_ENABLED_CATEGORY = "breakpoint-enabled-category";
 const char* BREAKPOINT_DISABLED_CATEGORY = "breakpoint-disabled-category";
+const char* COUNTPOINT_CATEGORY;
 const char* WHERE_CATEGORY = "line-pointer-category";
 
 const char* WHERE_MARK = "where-marker";
@@ -694,6 +695,9 @@ struct SourceEditor::Priv {
                                 (BREAKPOINT_DISABLED_CATEGORY,
                                  "icons/breakpoint-disabled-marker.png");
 
+	register_breakpoint_marker_type (COUNTPOINT_CATEGORY,
+					 "icons/countpoint-marker.png");
+
         // move cursor to the beginning of the file
         Glib::RefPtr<Gtk::TextBuffer> source_buffer = source_view->get_buffer ();
         source_buffer->place_cursor (source_buffer->begin ());
@@ -869,7 +873,9 @@ SourceEditor::unset_where_marker ()
 }
 
 bool
-SourceEditor::set_visual_breakpoint_at_line (int a_line, bool enabled)
+SourceEditor::set_visual_breakpoint_at_line (int a_line,
+					     bool a_is_count_point,
+					     bool enabled)
 {
     LOG_FUNCTION_SCOPE_NORMAL_DD
 
@@ -885,6 +891,9 @@ SourceEditor::set_visual_breakpoint_at_line (int a_line, bool enabled)
 
     UString marker_type;
     if (enabled) {
+      if (a_is_count_point)
+	marker_type = COUNTPOINT_CATEGORY;
+      else
         marker_type = BREAKPOINT_ENABLED_CATEGORY;
     } else {
         marker_type = BREAKPOINT_DISABLED_CATEGORY;
@@ -1535,13 +1544,15 @@ SourceEditor::get_assembly_source_buffer () const
 
 bool
 SourceEditor::set_visual_breakpoint_at_address (const Address &a_address,
+						bool a_is_count_point,
                                                 bool a_enabled)
 {
     int line = -1;
     if (!assembly_buf_addr_to_line (a_address, false, line))
         return false;
-    return set_visual_breakpoint_at_line (line, a_enabled);
-
+    return set_visual_breakpoint_at_line (line,
+					  a_is_count_point,
+					  a_enabled);
 }
 
 /// Remove the marker that represents a breakpoint at a given machine
diff --git a/src/uicommon/nmv-source-editor.h b/src/uicommon/nmv-source-editor.h
index 37bcfbb..d1b0600 100644
--- a/src/uicommon/nmv-source-editor.h
+++ b/src/uicommon/nmv-source-editor.h
@@ -45,10 +45,11 @@ using nemiver::common::Address;
 using std::list;
 using std::map;
 
-namespace nemiver {
+NEMIVER_BEGIN_NAMESPACE (nemiver);
 
 extern const char* BREAKPOINT_ENABLED_CATEGORY;
 extern const char* BREAKPOINT_DISABLED_CATEGORY;
+extern const char* COUNTPOINT_CATEGORY;
 extern const char* WHERE_CATEGORY;
 
 extern const char* WHERE_MARK;
@@ -84,7 +85,9 @@ public:
     void current_column (int &a_col);
     bool move_where_marker_to_line (int a_line, bool a_do_scroll = true);
     void unset_where_marker ();
-    bool set_visual_breakpoint_at_line (int a_line, bool enabled = true);
+    bool set_visual_breakpoint_at_line (int a_line,
+					bool a_is_count_point,
+					bool a_enabled);
     bool remove_visual_breakpoint_from_line (int a_line);
     void clear_decorations ();
     bool is_visual_breakpoint_set_at_line (int a_line) const;
@@ -162,7 +165,8 @@ public:
     bool place_cursor_at_line (size_t);
     bool place_cursor_at_address (const Address &);
     bool set_visual_breakpoint_at_address (const Address &a_address,
-                                           bool enabled = true);
+					   bool is_countpoint,
+                                           bool enabled);
     bool remove_visual_breakpoint_from_address (const Address &);
     bool scroll_to_address (const Address &a_address,
 			    bool a_approximate);
@@ -197,7 +201,7 @@ public:
     /// @}
 };//end class SourceEditor
 
-}//end namespace nemiver
+NEMIVER_END_NAMESPACE (nemiver)
 
 #endif //__NEMIVER_DBG_SOURCE_EDITOR_H__
 



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