[nemiver] Support follow-fork-mode setting (Closes: #581377)



commit 7f0b1955dbe320f607962d5c3e9e0e99e3cd8421
Author: Dodji Seketeli <dodji gnome org>
Date:   Thu May 6 10:36:30 2010 +0200

    Support follow-fork-mode setting (Closes: #581377)
    
    	* src/common/nmv-env.cc (CONF_KEY_FOLLOW_FORK_MODE): Define new
    	gconf key.
    	* src/persp/dbgperspective/nmv-conf-keys.h: Declare new key
    	CONF_KEY_FOLLOW_FORK_MODE.
    	* src/dbgengine/nmv-gdb-engine.cc (CONF_KEY_FOLLOW_FORK_MODE):
    	declare new key.
    	(struct GDBEngine::Priv)<follow_fork_mode>: New attribute.
    	Initialize it to "parent".
    	(GDBEngine::Priv::launch_gdb_and_set_args): Set the default
    	follow-fork-mode when launching GDB.
    	(GDBEngine::Priv::set_debugger_parameter): Factorize this out
    	from ...
    	(GDBEngine::set_debugger_parameter): ... here. Use the new
    	GDBEngine::Priv::set_debugger_parameter.
    	(GDBEngine::Priv::read_default_config,
    	 GDBEngine::Priv::on_conf_key_changed_signal): New fns.
    	(GDBEngine::Priv::on_conf_key_changed_signal):
    	(GDBEngine::Priv::get_conf_mgr): Do not create our own conf mgr
    	here. Rather, use the one passed to us at GDBEngine::do_init time.
    	(GDBEngine::do_init): Connect to the value_changed_signal of the
    	 conf manager we are initialized with.
    	* src/dbgengine/nmv-i-debugger.h (IDebugger::do_init): Don't
    	pass safeptrs by reference.
    	* src/dbgengine/nmv-gdb-engine.h (GDBEngine::do_init): Likewise.
    	* src/persp/dbgperspective/glade/preferencesdialog.glade: Add
    	UI to set follow-fork-mode.
    	* src/persp/dbgperspective/nmv-preferences-dialog.cc
    	(PreferencesDialog::Priv::on_follow_fork_mode_toggle_signal,
    	 PreferencesDialog::Priv::update_follow_fork_mode_key):
    	New fns.
    	(PreferencesDialog::Priv::init): Get the radio buttons to set the
    	follow-fork-mode. Connect their toggled signal to the new
    	PreferencesDialog::Priv::on_follow_fork_mode_toggle_signal
    	(PreferencesDialog::Priv::update_widget_from_debugger_keys):
    	Pull the CONF_KEY_FOLLOW_FORK_MODE key value and initialize the
    	follow-fork-mode radio buttons with it.
    	* src/persp/dbgperspective/schemas/nemiver-dbgperspective.schemas:
    	Add a new string key /apps/nemiver/dbgperspective/follow-fork-mode.

 src/common/nmv-env.cc                              |    2 +
 src/dbgengine/nmv-gdb-engine.cc                    |   60 +++++++++----
 src/dbgengine/nmv-gdb-engine.h                     |    2 +-
 src/dbgengine/nmv-i-debugger.h                     |    2 +-
 .../dbgperspective/glade/preferencesdialog.glade   |   98 ++++++++++++++++++++
 src/persp/dbgperspective/nmv-conf-keys.h           |    2 +
 src/persp/dbgperspective/nmv-preferences-dialog.cc |   53 ++++++++++-
 .../schemas/nemiver-dbgperspective.schemas         |   13 +++
 8 files changed, 212 insertions(+), 20 deletions(-)
---
diff --git a/src/common/nmv-env.cc b/src/common/nmv-env.cc
index cac974f..eb7aa52 100644
--- a/src/common/nmv-env.cc
+++ b/src/common/nmv-env.cc
@@ -43,6 +43,8 @@ using namespace std;
 NEMIVER_BEGIN_NAMESPACE (nemiver)
 
 const char *CONF_KEY_GDB_BINARY = "/apps/nemiver/dbgperspective/gdb-binary";
+const char *CONF_KEY_FOLLOW_FORK_MODE = "/apps/nemiver/dbgperspective"
+                                        "/follow-fork-mode";
 
 NEMIVER_BEGIN_NAMESPACE (common)
 NEMIVER_BEGIN_NAMESPACE (env)
diff --git a/src/dbgengine/nmv-gdb-engine.cc b/src/dbgengine/nmv-gdb-engine.cc
index 1bbeb9f..6034c5b 100644
--- a/src/dbgengine/nmv-gdb-engine.cc
+++ b/src/dbgengine/nmv-gdb-engine.cc
@@ -55,6 +55,7 @@ static const UString DEFAULT_GDB_BINARY = "default-gdb-binary";
 NEMIVER_BEGIN_NAMESPACE (nemiver)
 
 extern const char* CONF_KEY_GDB_BINARY;
+extern const char* CONF_KEY_FOLLOW_FORK_MODE;
 
 // Helper function to handle escaping the arguments 
 static UString
@@ -124,6 +125,7 @@ public:
     Address cur_frame_address;
     ILangTraitSafePtr lang_trait;
     UString debugger_full_path;
+    UString follow_fork_mode;
     GDBMIParser gdbmi_parser;
     sigc::signal<void> gdb_died_signal;
     sigc::signal<void, const UString& > master_pty_signal;
@@ -298,16 +300,6 @@ public:
 
     IConfMgrSafePtr get_conf_mgr () const
     {
-        if (!conf_mgr) {
-            THROW_IF_FAIL (dynmod);
-            DynamicModule::Loader *loader = dynmod->get_module_loader ();
-            THROW_IF_FAIL (loader);
-            DynamicModuleManager *module_manager =
-                                        loader->get_dynamic_module_manager ();
-            THROW_IF_FAIL (module_manager);
-            conf_mgr = module_manager->load_iface<IConfMgr> ("gconfmgr",
-                                                             "IConfMgr");
-        }
         THROW_IF_FAIL (conf_mgr);
         return conf_mgr;
     }
@@ -451,6 +443,7 @@ public:
         state (IDebugger::NOT_STARTED),
         cur_frame_level (0),
         cur_thread_num (1),
+        follow_fork_mode ("parent"),
         gdbmi_parser (GDBMIParser::BROKEN_MODE)
     {
         gdb_stdout_signal.connect (sigc::mem_fun
@@ -471,7 +464,6 @@ public:
 
         frames_listed_signal.connect (sigc::mem_fun
                (*this, &Priv::on_frames_listed_signal));
-
     }
 
     void free_resources ()
@@ -695,6 +687,7 @@ public:
         if (!args.empty ()) {
             return issue_command (Command ("set args " + args));
         }
+        set_debugger_parameter ("follow-fork-mode", follow_fork_mode);
 
         return true;
     }
@@ -758,6 +751,23 @@ public:
         return result;
     }
 
+    void set_debugger_parameter (const UString &a_name,
+                                 const UString &a_value)
+    {
+
+        LOG_FUNCTION_SCOPE_NORMAL_DD;
+        if (a_name == "")
+            return;
+        UString param_str = a_name + " " + a_value;
+        queue_command (Command ("set-debugger-parameter", "set " + param_str));
+    }
+
+    void read_default_config ()
+    {
+        get_conf_mgr ()->get_key_value (CONF_KEY_FOLLOW_FORK_MODE,
+                                        follow_fork_mode);
+    }
+
     void list_frames (int a_low_frame,
                       int a_high_frame,
                       const UString &a_cookie)
@@ -973,6 +983,19 @@ public:
         NEMIVER_CATCH_NOX
     }
 
+    void on_conf_key_changed_signal (const UString &a_key,
+                                     IConfMgr::Value &a_value)
+    {
+        NEMIVER_TRY
+
+        if (a_key == CONF_KEY_FOLLOW_FORK_MODE) {
+            follow_fork_mode = boost::get<UString> (a_value).raw ();
+            set_debugger_parameter ("follow-fork-mode", follow_fork_mode);
+        }
+
+        NEMIVER_CATCH_NOX
+    }
+
     bool breakpoint_has_failed (const CommandAndOutput &a_in)
     {
         if (a_in.has_command ()
@@ -3295,12 +3318,18 @@ GDBEngine::init ()
     init_output_handlers ();
 }
 
+// Put here the initialization that must happen once our call call us
+// For initialization, i.e, after we are sure we have stuff like conf
+// manager ready, etc ...
 void
-GDBEngine::do_init (IConfMgrSafePtr &a_conf_mgr)
+GDBEngine::do_init (IConfMgrSafePtr a_conf_mgr)
 {
+    m_priv->conf_mgr = a_conf_mgr;
 
+    m_priv->read_default_config ();
 
-    m_priv->conf_mgr = a_conf_mgr;
+    m_priv->get_conf_mgr ()->value_changed_signal ().connect (sigc::mem_fun
+        (*m_priv, &Priv::on_conf_key_changed_signal));
 }
 
 IConfMgr&
@@ -3368,10 +3397,7 @@ GDBEngine::set_debugger_parameter (const UString &a_name,
                                    const UString &a_value)
 {
     LOG_FUNCTION_SCOPE_NORMAL_DD;
-    if (a_name == "")
-        return;
-    UString param_str = a_name + " " + a_value;
-    queue_command (Command ("set-debugger-parameter", "set " + param_str));
+    m_priv->set_debugger_parameter (a_name, a_value);
 }
 
 void
diff --git a/src/dbgengine/nmv-gdb-engine.h b/src/dbgengine/nmv-gdb-engine.h
index c6ae313..7998a93 100644
--- a/src/dbgengine/nmv-gdb-engine.h
+++ b/src/dbgengine/nmv-gdb-engine.h
@@ -225,7 +225,7 @@ public:
     void init ();
 
     // to be called by client code
-    void do_init (IConfMgrSafePtr &a_conf_mgr);
+    void do_init (IConfMgrSafePtr a_conf_mgr);
 
     IConfMgr& get_conf_mgr ();
 
diff --git a/src/dbgengine/nmv-i-debugger.h b/src/dbgengine/nmv-i-debugger.h
index e83741a..c10232d 100644
--- a/src/dbgengine/nmv-i-debugger.h
+++ b/src/dbgengine/nmv-i-debugger.h
@@ -1176,7 +1176,7 @@ public:
                 assigned_variable_signal () const = 0;
     /// @}
 
-    virtual void do_init (IConfMgrSafePtr &a_conf_mgr) = 0;
+    virtual void do_init (IConfMgrSafePtr a_conf_mgr) = 0;
 
     virtual map<UString, UString>& properties () = 0;
 
diff --git a/src/persp/dbgperspective/glade/preferencesdialog.glade b/src/persp/dbgperspective/glade/preferencesdialog.glade
index ece3da0..6034c8d 100644
--- a/src/persp/dbgperspective/glade/preferencesdialog.glade
+++ b/src/persp/dbgperspective/glade/preferencesdialog.glade
@@ -1107,6 +1107,104 @@
 		  <property name="fill">True</property>
 		</packing>
 	      </child>
+
+	      <child>
+		<widget class="GtkFrame" id="frame10">
+		  <property name="visible">True</property>
+		  <property name="label_xalign">0</property>
+		  <property name="label_yalign">0.5</property>
+		  <property name="shadow_type">GTK_SHADOW_NONE</property>
+
+		  <child>
+		    <widget class="GtkAlignment" id="alignment11">
+		      <property name="visible">True</property>
+		      <property name="xalign">0.5</property>
+		      <property name="yalign">0.5</property>
+		      <property name="xscale">1</property>
+		      <property name="yscale">1</property>
+		      <property name="top_padding">6</property>
+		      <property name="bottom_padding">0</property>
+		      <property name="left_padding">12</property>
+		      <property name="right_padding">0</property>
+
+		      <child>
+			<widget class="GtkVBox" id="vbox9">
+			  <property name="visible">True</property>
+			  <property name="homogeneous">False</property>
+			  <property name="spacing">0</property>
+
+			  <child>
+			    <widget class="GtkRadioButton" id="followparentradio">
+			      <property name="visible">True</property>
+			      <property name="can_focus">True</property>
+			      <property name="label" translatable="yes">Follow parent</property>
+			      <property name="use_underline">True</property>
+			      <property name="relief">GTK_RELIEF_NORMAL</property>
+			      <property name="focus_on_click">True</property>
+			      <property name="active">False</property>
+			      <property name="inconsistent">False</property>
+			      <property name="draw_indicator">True</property>
+			    </widget>
+			    <packing>
+			      <property name="padding">0</property>
+			      <property name="expand">False</property>
+			      <property name="fill">False</property>
+			    </packing>
+			  </child>
+
+			  <child>
+			    <widget class="GtkRadioButton" id="followchildradio">
+			      <property name="visible">True</property>
+			      <property name="can_focus">True</property>
+			      <property name="label" translatable="yes">Follow child</property>
+			      <property name="use_underline">True</property>
+			      <property name="relief">GTK_RELIEF_NORMAL</property>
+			      <property name="focus_on_click">True</property>
+			      <property name="active">False</property>
+			      <property name="inconsistent">False</property>
+			      <property name="draw_indicator">True</property>
+			      <property name="group">followparentradio</property>
+			    </widget>
+			    <packing>
+			      <property name="padding">0</property>
+			      <property name="expand">False</property>
+			      <property name="fill">False</property>
+			    </packing>
+			  </child>
+			</widget>
+		      </child>
+		    </widget>
+		  </child>
+
+		  <child>
+		    <widget class="GtkLabel" id="label17">
+		      <property name="visible">True</property>
+		      <property name="label" translatable="yes">&lt;b&gt;GDB follow fork mode&lt;/b&gt;</property>
+		      <property name="use_underline">False</property>
+		      <property name="use_markup">True</property>
+		      <property name="justify">GTK_JUSTIFY_LEFT</property>
+		      <property name="wrap">False</property>
+		      <property name="selectable">False</property>
+		      <property name="xalign">0.5</property>
+		      <property name="yalign">0.5</property>
+		      <property name="xpad">0</property>
+		      <property name="ypad">0</property>
+		      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		      <property name="width_chars">-1</property>
+		      <property name="single_line_mode">False</property>
+		      <property name="angle">0</property>
+		    </widget>
+		    <packing>
+		      <property name="type">label_item</property>
+		    </packing>
+		  </child>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">True</property>
+		  <property name="fill">True</property>
+		</packing>
+	      </child>
 	    </widget>
 	    <packing>
 	      <property name="tab_expand">False</property>
diff --git a/src/persp/dbgperspective/nmv-conf-keys.h b/src/persp/dbgperspective/nmv-conf-keys.h
index b7412bd..acd965b 100644
--- a/src/persp/dbgperspective/nmv-conf-keys.h
+++ b/src/persp/dbgperspective/nmv-conf-keys.h
@@ -47,6 +47,8 @@ extern const char* CONF_KEY_EDITOR_STYLE_SCHEME;
 extern const char* CONF_KEY_ASM_STYLE_PURE;
 extern const char* CONF_KEY_GDB_BINARY;
 extern const char* CONF_KEY_DEFAULT_NUM_ASM_INSTRS;
+extern const char* CONF_KEY_FOLLOW_FORK_MODE;
+
 NEMIVER_END_NAMESPACE (nemiver)
 
 #endif // __NMV_CONF_KEYS_H__
diff --git a/src/persp/dbgperspective/nmv-preferences-dialog.cc b/src/persp/dbgperspective/nmv-preferences-dialog.cc
index ca01490..0e9e276 100644
--- a/src/persp/dbgperspective/nmv-preferences-dialog.cc
+++ b/src/persp/dbgperspective/nmv-preferences-dialog.cc
@@ -89,6 +89,8 @@ public:
     Gtk::RadioButton *confirm_reload_radio_button;
     Gtk::RadioButton *pure_asm_radio_button;
     Gtk::RadioButton *mixed_asm_radio_button;
+    Gtk::RadioButton *follow_parent_radio_button;
+    Gtk::RadioButton *follow_child_radio_button;
     Gtk::SpinButton  *default_num_asm_instrs_spin_button;
     Gtk::FileChooserButton *gdb_binary_path_chooser_button;
     Glib::RefPtr<Gnome::Glade::Xml> glade;
@@ -109,6 +111,8 @@ public:
         confirm_reload_radio_button (0),
         pure_asm_radio_button (0),
         mixed_asm_radio_button (0),
+        follow_parent_radio_button (0),
+        follow_child_radio_button (0),
         default_num_asm_instrs_spin_button (0),
         gdb_binary_path_chooser_button (0),
         glade (a_glade)
@@ -217,6 +221,11 @@ public:
         update_gdb_binary_key ();
     }
 
+    void on_follow_fork_mode_toggle_signal ()
+    {
+        update_follow_fork_mode_key ();
+    }
+
     void init ()
     {
 
@@ -406,6 +415,23 @@ public:
                  (*this,
                   &PreferencesDialog::Priv::on_gdb_binary_file_set_signal));
 
+        follow_parent_radio_button =
+        ui_utils::get_widget_from_glade<Gtk::RadioButton> (glade,
+                                                           "followparentradio");
+        THROW_IF_FAIL (follow_parent_radio_button);
+        follow_parent_radio_button->signal_toggled ().connect
+            (sigc::mem_fun
+                 (*this,
+                  &PreferencesDialog::Priv::on_follow_fork_mode_toggle_signal));
+
+        follow_child_radio_button =
+        ui_utils::get_widget_from_glade<Gtk::RadioButton> (glade,
+                                                           "followchildradio");
+        THROW_IF_FAIL (follow_child_radio_button);
+        follow_child_radio_button->signal_toggled ().connect
+            (sigc::mem_fun
+                 (*this,
+                  &PreferencesDialog::Priv::on_follow_fork_mode_toggle_signal));
     }
 
     void collect_source_dirs ()
@@ -571,6 +597,20 @@ public:
                                        Glib::filename_from_utf8 (path));
     }
 
+    void update_follow_fork_mode_key ()
+    {
+        THROW_IF_FAIL (follow_parent_radio_button);
+        THROW_IF_FAIL (follow_child_radio_button);
+
+        UString mode = "parent";
+        if (follow_parent_radio_button->get_active ())
+            /*mode = "parent"*/;
+        else if (follow_child_radio_button->get_active ())
+            mode = "child";
+
+        conf_manager ().set_key_value (CONF_KEY_FOLLOW_FORK_MODE, mode);
+    }
+
     void update_widget_from_editor_keys ()
     {
         THROW_IF_FAIL (show_lines_check_button);
@@ -681,11 +721,22 @@ public:
 
         UString gdb_binary = common::env::get_gdb_program ();
         if (!conf_manager ().get_key_value (CONF_KEY_GDB_BINARY, gdb_binary)) {
-            LOG_ERROR ("failed to get gconf key" << CONF_KEY_GDB_BINARY);
+            LOG_ERROR ("failed to get gconf key " << CONF_KEY_GDB_BINARY);
         }
         gdb_binary_path_chooser_button->set_filename
             (Glib::filename_to_utf8 (gdb_binary));
 
+        UString follow_fork_mode = "parent";
+        if (!conf_manager ().get_key_value (CONF_KEY_FOLLOW_FORK_MODE,
+                                           follow_fork_mode)) {
+            LOG_ERROR ("failed to get gconf key "
+                       << CONF_KEY_FOLLOW_FORK_MODE);
+        }
+        if (follow_fork_mode == "parent") {
+            follow_parent_radio_button->set_active (true);
+        } else if (follow_fork_mode == "child") {
+            follow_child_radio_button->set_active (true);
+        }
     }
 
     void update_widget_from_conf ()
diff --git a/src/persp/dbgperspective/schemas/nemiver-dbgperspective.schemas b/src/persp/dbgperspective/schemas/nemiver-dbgperspective.schemas
index 5a2e023..78af336 100644
--- a/src/persp/dbgperspective/schemas/nemiver-dbgperspective.schemas
+++ b/src/persp/dbgperspective/schemas/nemiver-dbgperspective.schemas
@@ -194,6 +194,19 @@ to assembly view. Otherwise, source code mixed with assembly code is shown.</lon
       </locale>
     </schema>
     <schema>
+      <key>/schemas/apps/nemiver/dbgperspective/follow-fork-mode</key>
+      <applyto>/apps/nemiver/dbgperspective/follow-fork-mode</applyto>
+      <owner>nemiver</owner>
+      <type>string</type>
+      <default>parent</default>
+      <locale name="C">
+	<short>Which process to follow upon a fork</short>
+	<long>If a fork happen, follow the parent parent process if the
+key is set to 'parent', or follow the child process if the key is set to
+ 'child'</long>
+      </locale>
+    </schema>
+    <schema>
       <key>/schemas/apps/nemiver/dbgperspective/callstack-expansion-chunk</key>
       <applyto>/apps/nemiver/dbgperspective/callstack-expansion-chunk</applyto>
       <owner>nemiver</owner>



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