[nemiver] Don't 'run' the inferior on startup when it has no 'main'



commit cc80c596359ab8c5f650ffec88dd7636852eece6
Author: Dodji Seketeli <dodji seketeli org>
Date:   Sun Jun 2 19:49:57 2013 +0200

    Don't 'run' the inferior on startup when it has no 'main'
    
        * src/dbgengine/nmv-i-debugger.h (IDebugger::set_breakpoint):
        Declare a new overload that sets a breakpoint on a function by
        name and that takes a callback slot that is invoked whenever the
        breakpoint is set.
        * src/dbgengine/nmv-gdb-engine.h (GDBEngine::set_breakpoint):
        Declare ...
        * src/dbgengine/nmv-gdb-engine.cc (GDBEngine::set_breakpoint):
        ... a new overload that sets a breakpoint on a function by name
        and that takes a callback slot that is invoked whenever the
        breakpoint is set.  Write the previous overload that just set a
        breakpoint on a function by name in terms of this new one.
        * src/persp/dbgperspective/nmv-dbg-perspective.cc
        (DBGPerspective::on_debugger_breakpoints_set_signal): New callback slot.
        (DBGPerspective::execute_program): It's only if the breakpoint set
        on main is actually set that the inferior should be run.

 src/dbgengine/nmv-gdb-engine.cc                 |   48 ++++++++++++-
 src/dbgengine/nmv-gdb-engine.h                  |    6 ++
 src/dbgengine/nmv-i-debugger.h                  |    6 ++
 src/persp/dbgperspective/nmv-dbg-perspective.cc |   86 +++++++++++++++++++----
 4 files changed, 130 insertions(+), 16 deletions(-)
---
diff --git a/src/dbgengine/nmv-gdb-engine.cc b/src/dbgengine/nmv-gdb-engine.cc
index 96b9906..cf0d4b7 100644
--- a/src/dbgengine/nmv-gdb-engine.cc
+++ b/src/dbgengine/nmv-gdb-engine.cc
@@ -4841,8 +4841,52 @@ GDBEngine::set_watchpoint (const UString &a_expression,
     list_breakpoints (a_cookie);
 }
 
+/// Set a breakpoint to a function name.
+///
+/// \param a_func_name the name of the function to set the breakpoint to.
+///
+/// \param a_condition the condition of the breakption.  This is a
+/// string containing an expression that is to be evaluated in the
+/// context of the inferior, at the source location of the breakpoint.
+/// Once the breakpoint is set, code execution will stop at the
+/// breakpoint iff the condition evaluates to true.
+///
+/// \param a_ignore_count the number of time the breakpoint must be
+/// hit, before execution is stopped.
+///
+/// \param a_cookie a string that is passed to the callback slot.
+void
+GDBEngine::set_breakpoint (const UString &a_func_name,
+                           const UString &a_condition,
+                           gint a_ignore_count,
+                           const UString &a_cookie)
+{
+    LOG_FUNCTION_SCOPE_NORMAL_DD;
+
+    set_breakpoint (a_func_name, &null_breakpoints_slot,
+                    a_condition, a_ignore_count, a_cookie);
+}
+
+/// Set a breakpoint to a function name, and have a callback slot be
+/// invoked when/if the breakpoint is set.
+///
+/// \param a_func_name the name of the function to set the breakpoint to.
+///
+/// \param a_slot the callback slot to set the breakpoint to.
+///
+/// \param a_condition the condition of the breakption.  This is a
+/// string containing an expression that is to be evaluated in the
+/// context of the inferior, at the source location of the breakpoint.
+/// Once the breakpoint is set, code execution will stop at the
+/// breakpoint iff the condition evaluates to true.
+///
+/// \param a_ignore_count the number of time the breakpoint must be
+/// hit, before execution is stopped.
+///
+/// \param a_cookie a string that is passed to the callback slot.
 void
 GDBEngine::set_breakpoint (const UString &a_func_name,
+                           const BreakpointsSlot &a_slot,
                            const UString &a_condition,
                            gint a_ignore_count,
                            const UString &a_cookie)
@@ -4860,7 +4904,9 @@ GDBEngine::set_breakpoint (const UString &a_func_name,
     break_cmd += " -i " + UString::from_int (a_ignore_count);
     break_cmd +=  " " + a_func_name;
 
-    queue_command (Command ("set-breakpoint", break_cmd, a_cookie));
+    Command command ("set-breakpoint", break_cmd, a_cookie);
+    command.set_slot (a_slot);
+    queue_command (command);
 }
 
 void
diff --git a/src/dbgengine/nmv-gdb-engine.h b/src/dbgengine/nmv-gdb-engine.h
index 28abeaa..2c5d97e 100644
--- a/src/dbgengine/nmv-gdb-engine.h
+++ b/src/dbgengine/nmv-gdb-engine.h
@@ -393,6 +393,12 @@ public:
                          gint a_ignore_count,
                          const UString &a_cookie);
 
+    void  set_breakpoint (const UString &a_func_name,
+                          const BreakpointsSlot &a_slot,
+                          const UString &a_condition,
+                          gint a_ignore_count,
+                          const UString &a_cookie);
+
     void set_breakpoint (const Address &a_address,
                          const UString &a_condition,
                          gint a_ignore_count,
diff --git a/src/dbgengine/nmv-i-debugger.h b/src/dbgengine/nmv-i-debugger.h
index 81bbc5e..527f071 100644
--- a/src/dbgengine/nmv-i-debugger.h
+++ b/src/dbgengine/nmv-i-debugger.h
@@ -1412,6 +1412,12 @@ public:
                                  gint a_ignore_count = 0,
                                  const UString &a_cookie = "") = 0;
 
+        virtual void set_breakpoint (const UString &a_func_name,
+                                     const BreakpointsSlot &a_slot,
+                                     const UString &a_condition = "",
+                                     gint a_ignore_count = 0,
+                                     const UString &a_cookie = "") = 0;
+
     virtual void set_breakpoint (const Address &a_address,
                                  const UString &a_condition = "",
                                  gint a_ignore_count = 0,
diff --git a/src/persp/dbgperspective/nmv-dbg-perspective.cc b/src/persp/dbgperspective/nmv-dbg-perspective.cc
index a00311d..b2dbcf5 100644
--- a/src/persp/dbgperspective/nmv-dbg-perspective.cc
+++ b/src/persp/dbgperspective/nmv-dbg-perspective.cc
@@ -351,6 +351,9 @@ private:
     void on_debugger_breakpoints_set_signal
     (const std::map<string, IDebugger::Breakpoint>&, const UString&);
 
+    void on_debugger_bp_automatically_set_on_main
+    (const map<string, IDebugger::Breakpoint>&, bool);
+
     void on_debugger_breakpoints_list_signal
                                 (const map<string, IDebugger::Breakpoint> &,
                                  const UString &a_cookie);
@@ -2376,7 +2379,48 @@ DBGPerspective::on_debugger_breakpoints_set_signal
 (const std::map<string, IDebugger::Breakpoint> &a,
  const UString&)
 {
+    NEMIVER_TRY;
+
     append_breakpoints (a);
+
+    NEMIVER_CATCH;
+}
+
+/// This callback slot is invoked when the breakpoint that is
+/// automatically set to the 'main' function upon startup is set.
+///
+/// The goal here is to detect that the breakpoint is actually set to
+/// the 'main' entry point (that would mean that a 'main' entry point
+/// function exists and one can set a breakpoint there).  In that
+/// case, the function makes the debugger 'run', so that execution of
+/// the inferior stops at the main entry point.
+///
+/// Otherwise, if no 'main' entry point exists or can be broke at, the
+/// debugger does nothing.  The user will have to set a breakpoint at
+/// a place of her choice and run the debugger so that it stops there.
+///
+/// \param a_bps the set of breakpoints that are set.
+///
+/// \param a_restarting whether the debugger is re-starting, or just
+/// starting for the first time.
+void
+DBGPerspective::on_debugger_bp_automatically_set_on_main
+(const map<string, IDebugger::Breakpoint>& a_bps,
+ bool a_restarting)
+{
+    NEMIVER_TRY;
+
+    for (map<string, IDebugger::Breakpoint>::const_iterator i = a_bps.begin ();
+         i != a_bps.end ();
+         ++i) {
+        if (i->second.function () == "main"
+            && !i->second.address ().empty ()) {
+            run_real (a_restarting);
+            return;
+        }
+    }
+
+    NEMIVER_CATCH;
 }
 
 void
@@ -6036,24 +6080,33 @@ DBGPerspective::execute_program (const UString &a_prog,
 /// This function can also set breakpoints before running the inferior.
 ///
 /// \param a_prog the path to the program to debug
+///
 /// \param a_args the arguments of the program to debug
-/// \param a_env  the environment variables to set prior
-///               to running the inferior. Those environment variables
-///               will be accessible to the inferior.
+///
+/// \param a_env the environment variables to set prior to running the
+///  inferior. Those environment variables will be accessible to the
+///  inferior.
+///
 /// \param a_cwd the working directory in which to run the inferior
+///
 /// \param a_breaks the breakpoints to set prior to running the inferior.
+///
 /// \param a_close_opened_files if true, close the files that have been
 ///        opened in the debugging perspective.
-/// \param a_restarting if true, be kind if the program to run
-///        has be run previously. Be kind means things like do not re do
-///        things that have been done already, e.g. re set breakpoints etc.
-///        Otherwise, just ignore the fact that the program might have been
-///        run previously and just redo all the necessary things.
+///
+/// \param a_restarting if true, be kind if the program to run has be
+///  run previously. Be kind means things like do not re do things
+///  that have been done already, e.g. re set breakpoints etc.
+///  Otherwise, just ignore the fact that the program might have been
+///  run previously and just redo all the necessary things.
+///
 /// \param a_close_opened_files if true, close all the opened files
-///        before executing the inferior.
+///  before executing the inferior.
+///
 /// \param a_break_in_main_run if true, set a breakpoint in the "main"
-///        function of the inferior and run it.  The inferior will
-///        then run and stop at the beginning of the main function.
+///  function of the inferior and, if the breakpoint is actually set
+///  there, then run it.  The inferior will then run and stop at the
+///  beginning of the main function.
 void
 DBGPerspective::execute_program
                         (const UString &a_prog,
@@ -6178,7 +6231,13 @@ DBGPerspective::execute_program
                 set_breakpoint (it->second);
             }
         } else if (a_break_in_main_run) {
-            dbg_engine->set_breakpoint ("main");
+            dbg_engine->set_breakpoint
+                ("main",
+                 sigc::bind
+                 (sigc::mem_fun
+                  (*this,
+                   &DBGPerspective::on_debugger_bp_automatically_set_on_main),
+                  a_restarting));
         }
     } else {
         vector<IDebugger::Breakpoint>::const_iterator it;
@@ -6187,9 +6246,6 @@ DBGPerspective::execute_program
         }
     }
 
-    if (a_break_in_main_run)
-        run_real (a_restarting);
-
     m_priv->last_prog_path_requested = prog;
     m_priv->prog_path = prog;
     m_priv->prog_args = a_args;


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