[geany/geany-plugins] bcd1f5: scope - easier sync between GDB/Scope thread/frame, small fixes

Dimitar Zhekov git-noreply at geany.org
Thu Dec 27 18:43:16 UTC 2012


Branch:      refs/heads/master
Author:      Dimitar Zhekov <dimitar.zhekov at gmail.com>
Committer:   Dimitar Zhekov <dimitar.zhekov at gmail.com>
Date:        Thu, 27 Dec 2012 18:43:16 UTC
Commit:      bcd1f59cf85bcd3d783ea5c351cf4c9ea0fb28b4
             https://github.com/geany/geany-plugins/commit/bcd1f59cf85bcd3d783ea5c351cf4c9ea0fb28b4

Log Message:
-----------
scope - easier sync between GDB/Scope thread/frame, small fixes


Modified Paths:
--------------
    scope/ChangeLog
    scope/NEWS
    scope/data/scope.glade
    scope/docs/codes.html
    scope/docs/scope.html
    scope/src/break.c
    scope/src/inspect.c
    scope/src/local.c
    scope/src/menu.c
    scope/src/parse.c
    scope/src/program.c
    scope/src/scope.c
    scope/src/stack.c
    scope/src/stack.h
    scope/src/thread.c
    scope/src/thread.h
    scope/src/views.c
    scope/src/views.h
    scope/src/watch.c

Modified: scope/ChangeLog
28 files changed, 28 insertions(+), 0 deletions(-)
===================================================================
@@ -1,3 +1,27 @@
+2012-12-27  Dimitar Zhekov  <dimitar.zhekov at gmail.com>
+
+ * data/scope.glade, docs/codes.html, docs/scope.html, src/parse.c,
+   src/stack.c, src/stack.h, src/thread.c, src/thread.h, src/views.c:
+   Easier sync between GDB/Scope thread/frame.
+
+ * docs/scope.html, src/scope.c:
+   Increased version to 0.79.
+
+
+2012-12-26  Dimitar Zhekov  <dimitar.zhekov at gmail.com>
+
+ * data/scope.glade, docs/codes.html, src/break.c, src/inspect.c,
+   src/local.c, src/menu.c, src/stack.c, src/thread.c, src/views.h,
+   src/watch.c:
+   Small fixes, simplified menu action debug states.
+
+
+2012-12-24  Dimitar Zhekov  <dimitar.zhekov at gmail.com>
+
+ * src/thread.c:
+   Limit TerminateProcess() exit code to UINT_MAX, not NSIG.
+
+
 2012-12-23  Dimitar Zhekov  <dimitar.zhekov at gmail.com>
 
  * docs/scope.html, src/prefs.c, src/prefs.h, src/thread.c:
@@ -6,6 +30,7 @@
  * docs/scope.html, src/scope.c:
    Increased version to 0.78.
 
+
 2012-12-22  Dimitar Zhekov  <dimitar.zhekov at gmail.com>
 
  * NEWS:
@@ -18,12 +43,14 @@
    Removed parse_lead_locale(), not used.
  * src/program.c, src/scope.c:
    Unified error message format.
+
  
 2012-12-18  Dimitar Zhekov  <dimitar.zhekov at gmail.com>
 
  * build/scope.m4, scope/src/Makefile.am:
    No -lutil under win32.
 
+
 2012-12-16  Dimitar Zhekov  <dimitar.zhekov at gmail.com>
 
  * src/common.h, src/menu.h:
@@ -40,6 +67,7 @@
  * docs/scope.html, src/scope.c:
    Increased version to 0.77.
 
+
 2012-12-13  Dimitar Zhekov  <dimitar.zhekov at gmail.com>
 
  * data/scope.glade, src/local.c, src/parse.c, src/parse.h,


Modified: scope/NEWS
7 files changed, 7 insertions(+), 0 deletions(-)
===================================================================
@@ -1,12 +1,19 @@
+Scope 0.79 (2012-12-27)
+
+   * Easier sync between Scope/GDB thread/frame.
+
+
 Scope 0.78 (2012-12-23)
 
    * Added option "keep_exec_point" to keep the execution point marker
      and Threads location columns when a thread execution is resumed.
 
+
 Scope 0.77 (2012-12-16)
 
    * Support for " and \ in evaluate expressions.
 
+
 Scope 0.76 (2012-12-13)
 
    * Per-function display of @entry arguments.


Modified: scope/data/scope.glade
23 files changed, 22 insertions(+), 1 deletions(-)
===================================================================
@@ -461,6 +461,13 @@
       </object>
     </child>
     <child>
+      <object class="GtkMenuItem" id="thread_synchronize">
+        <property name="visible">True</property>
+        <property name="label" translatable="yes">S_ynchronize</property>
+        <property name="use_underline">True</property>
+      </object>
+    </child>
+    <child>
       <object class="GtkImageMenuItem" id="thread_interrupt">
         <property name="label" translatable="yes">_Interrupt</property>
         <property name="visible">True</property>
@@ -518,6 +525,13 @@
                 <property name="use_underline">True</property>
               </object>
             </child>
+            <child>
+              <object class="GtkCheckMenuItem" id="thread_select_follow">
+                <property name="visible">True</property>
+                <property name="label" translatable="yes">_Follow</property>
+                <property name="use_underline">True</property>
+              </object>
+            </child>
           </object>
         </child>
       </object>
@@ -651,9 +665,16 @@
       </object>
     </child>
     <child>
+      <object class="GtkMenuItem" id="stack_synchronize">
+        <property name="visible">True</property>
+        <property name="label" translatable="yes">S_ynchronize</property>
+        <property name="use_underline">True</property>
+      </object>
+    </child>
+    <child>
       <object class="GtkCheckMenuItem" id="stack_show_entry">
         <property name="visible">True</property>
-        <property name="label" translatable="yes">Show _ at entry</property>
+        <property name="label" translatable="yes">_Show @entry</property>
         <property name="use_underline">True</property>
       </object>
     </child>


Modified: scope/docs/codes.html
22 files changed, 17 insertions(+), 5 deletions(-)
===================================================================
@@ -21,13 +21,13 @@
 
 <tr><td class="nowrap"> </td><td class="tab"> </td><td class="tab"> </td></tr>
 
-<tr><td class="nowrap">016source</td>
+<tr><td class="nowrap">010-file-exec-and-symbols</td>
 	<td class="tab">program startup</td>
-	<td class="tab">apply breaks/inspects, send autorun commands</td></tr>
+	<td class="tab">same as 011 if no run script, otherwise nop</td></tr>
 
-<tr><td class="nowrap">015-file-exec-and-symbols</td>
+<tr><td class="nowrap">011source</td>
 	<td class="tab">program startup</td>
-	<td class="tab">same as 016 if no run script, otherwise nop</td></tr>
+	<td class="tab">apply breaks/inspects, send autorun commands</td></tr>
 
 <tr><td class="nowrap"> </td><td class="tab"> </td><td class="tab"> </td></tr>
 
@@ -71,6 +71,10 @@
 	<td class="tab">re-<em>Apply</em> breakpoint (obsolete)</td>
 	<td class="tab">apply breakpoint (after being deleted in gdb)</td></tr>
 
+<tr><td class="nowrap">02-thread-info</td>
+	<td class="tab"><em>Synchronize</em> threads</td>
+	<td class="tab">refresh threads & select the current gdb thread</td></tr>
+
 <tr><td class="nowrap">02<tid>-stack-list-frames</td>
 	<td class="tab"><em>Refresh</em> stack</td>
 	<td class="tab">clear stack list and load stack frames into it</td></tr>
@@ -79,6 +83,10 @@
 	<td class="tab"><em>Refresh</em> stack</td>
 	<td class="tab">fill stack <em>Arguments</em> column</td></tr>
 
+<tr><td class="nowrap">02<tid>-stack-info-frame</td>
+	<td class="tab"><em>Syncronize</em> stack</td>
+	<td class="tab">select the current gdb frame</td></tr>
+
 <tr><td class="nowrap">02<tid><fid>-stack-list-variables</td>
 	<td class="tab"><em>Refresh</em> locals</td>
 	<td class="tab">clear locals list and load local variables into it</td></tr>
@@ -123,6 +131,10 @@
 	<td class="tab">views idle update</td>
 	<td class="tab">same as 02<tid>-stack-list-variables</td></tr>
 
+<tr><td class="nowrap">04<tid>-stack-info-frame</td>
+	<td class="tab">at stopped thread without frame</td>
+	<td class="tab">fill the thread columns</td></tr>
+
 <tr><td class="nowrap"> </td><td class="tab"> </td><td class="tab"> </td></tr>
 
 <tr><td class="nowrap">05</td>
@@ -134,7 +146,7 @@
 	<td class="tab">-''-</td></tr>
 
 <tr><td class="nowrap">-''-</td>
-	<td class="tab">after temp break insert <em>first loc</em></td>
+	<td class="tab">after temp break insert <em>1st loc</em></td>
 	<td class="tab">-''-</td></tr>
 
 <tr><td class="nowrap">05-list-features</td>


Modified: scope/docs/scope.html
18 files changed, 15 insertions(+), 3 deletions(-)
===================================================================
@@ -279,6 +279,11 @@
 
 <p>Commands starting with 0<digit> are used internally by Scope and will be blocked.</p>
 
+<p>Scope tries to keep track of the current gdb thread, and to emit a -thread-select command
+on <em>Send</em>/<em>Busy</em> if the gdb thread does not match the one (if any) selected in
+<em>Threads</em>. Tracking the current gdb frame asynchronously is impossible, so you must use
+a gdb frame selection command or --frame for the non-zero frames.</p>
+
 <p>Writing a full combo box for multi-line text is outside the scope of this project.</p>
 
 <p><b><a name="reset markers">Reset Markers</a></b></p>
@@ -322,6 +327,9 @@
 <p><em>Refresh</em> - will not append or remove threads, only update the currently listed
 ones.</p>
 
+<p><em>Synchronize</em> - refresh and select the current gdb thread. Shift-click:
+-thread-select.</p>
+
 <p><em>Interrupt</em> - *nix: SIGINT, win~1: DebugBreakProcess.</p>
 
 <p><em>Terminate</em> - *nix: SIGTERM, win~1: TerminateProcess.</p>
@@ -329,7 +337,7 @@
 <p>Both <em>Interrupt</em> and <em>Terminate</em> require an extra <em>Step</em> deliver a
 signal/*process to a stopped thread, and an extra <em>Step</em> to terminate a process.</p>
 
-<div><em>Re-select on</em>:</div>
+<div><em>Select on</em>:</div>
 <table border="0">
 <tr><td class="tab"><em>Running</em></td><td class="tab">Select a stopped thread (if any) when
 the current thread becomes running. Useful when starting/stopping lots of threads, but may be
@@ -339,6 +347,8 @@
 there is no stopped thread already selected).</td></tr>
 <tr><td class="tab"><em>Exited</em></td><td class="tab">Select a stopped thread (if any) when
 the current thread is exited.</td></tr>
+<tr><td class="tab"><em>Follow</em></td><td class="tab">Follow gdb =thread-selected. It'll be
+better to clear the other options.</td></tr>
 </table>
 
 <p><b><a name="break">Breakpoints</a></b></p>
@@ -361,7 +371,7 @@
 <p><em>Apply on run</em> is off by default for watchpoints, because they are often related to
 a local expression.</p>
 
-<p>Shift-Clicking <em>Apply</em> applies the breakpoint for the currently selected thread
+<p>Shift-clicking <em>Apply</em> applies the breakpoint for the currently selected thread
 only.</p>
 
 <p>GDB may report an error for invalid <em>Condition</em> and/or <em>Script</em>, but still
@@ -388,6 +398,8 @@
 <p>The function arguments are subject to 8-bit text conversion. Their individual modes may be
 set via <em>Locals</em>.</p>
 
+<p><em>Synchronize</em> - select the current gdb frame. Shift-click: -stack-select-frame.</p>
+
 <p><em>Show @entry</em> - display any @entry arguments reported by gdb for the selected frame
 function. Depends on GDB "print entry-values". Applies to <em>Locals</em> too.</p>
 
@@ -673,7 +685,7 @@
 
 <b><a name="copyright">Copyright</a></b>
 
-<p>Scope 0.78, Copyright (C) 2012 Dimitar Toshkov Zhekov</p>
+<p>Scope 0.79, Copyright (C) 2012 Dimitar Toshkov Zhekov</p>
 
 <p>The menu and toolbar icons are from <a href="http://netbeans.org">Netbeans</a>, except for
 BreakPoint.</p>


Modified: scope/src/break.c
2 files changed, 1 insertions(+), 1 deletions(-)
===================================================================
@@ -1238,7 +1238,7 @@ static void on_break_view_source(G_GNUC_UNUSED const MenuItem *menu_item)
 static MenuItem break_menu_items[] =
 {
 	{ "break_refresh",     on_break_refresh,     DS_SENDABLE,  NULL, NULL },
-	{ "break_unsorted",    on_break_unsorted,    DS_SORTABLE,  NULL, NULL },
+	{ "break_unsorted",    on_break_unsorted,    0,            NULL, NULL },
 	{ "break_view_source", on_break_view_source, DS_VIEWABLE,  NULL, NULL },
 	{ "break_insert",      on_break_insert,      DS_SENDABLE,  NULL, NULL },
 	{ "break_watch",       on_break_watch,       DS_SENDABLE,  NULL, NULL },


Modified: scope/src/inspect.c
16 files changed, 7 insertions(+), 9 deletions(-)
===================================================================
@@ -940,8 +940,6 @@ static void on_inspect_delete(G_GNUC_UNUSED const MenuItem *menu_item)
 		gtk_tree_store_remove(store, &iter);
 }
 
-#define DS_FRESHABLE DS_SENDABLE
-#define DS_INSPECTABLE DS_NOT_BUSY
 #define DS_EDITABLE (DS_BASICS | DS_EXTRA_2)
 #define DS_APPLIABLE (DS_SENDABLE | DS_EXTRA_3)
 #define DS_EXPANDABLE (DS_SENDABLE | DS_EXTRA_4)
@@ -956,13 +954,13 @@ static void on_inspect_delete(G_GNUC_UNUSED const MenuItem *menu_item)
 
 static MenuItem inspect_menu_items[] =
 {
-	{ "inspect_refresh",   on_inspect_refresh,        DS_FRESHABLE,   NULL, NULL },
-	{ "inspect_add",       on_inspect_add,            DS_INSPECTABLE, NULL, NULL },
-	{ "inspect_edit",      on_inspect_edit,           DS_EDITABLE,    NULL, NULL },
-	{ "inspect_apply",     on_inspect_apply,          DS_APPLIABLE,   NULL, NULL },
-	{ "inspect_expand",    on_inspect_expand,         DS_EXPANDABLE,  NULL, NULL },
-	{ "inspect_copy",      on_inspect_copy,           DS_COPYABLE,    NULL, NULL },
-	{ "inspect_format",    on_inspect_format_display, DS_FORMATABLE,  NULL, NULL },
+	{ "inspect_refresh",   on_inspect_refresh,        DS_SENDABLE,   NULL, NULL },
+	{ "inspect_add",       on_inspect_add,            DS_NOT_BUSY,   NULL, NULL },
+	{ "inspect_edit",      on_inspect_edit,           DS_EDITABLE,   NULL, NULL },
+	{ "inspect_apply",     on_inspect_apply,          DS_APPLIABLE,  NULL, NULL },
+	{ "inspect_expand",    on_inspect_expand,         DS_EXPANDABLE, NULL, NULL },
+	{ "inspect_copy",      on_inspect_copy,           DS_COPYABLE,   NULL, NULL },
+	{ "inspect_format",    on_inspect_format_display, DS_FORMATABLE, NULL, NULL },
 	FORMAT_ITEM("natural", FORMAT_NATURAL),
 	FORMAT_ITEM("decimal", FORMAT_DECIMAL),
 	FORMAT_ITEM("hex",     FORMAT_HEX),


Modified: scope/src/local.c
2 files changed, 1 insertions(+), 1 deletions(-)
===================================================================
@@ -230,7 +230,7 @@ static void on_local_mr_mode(const MenuItem *menu_item)
 static MenuItem local_menu_items[] =
 {
 	{ "local_refresh",    on_local_refresh,  DS_FRESHABLE,   NULL, NULL },
-	{ "local_unsorted",   on_local_unsorted, DS_SORTABLE,    NULL, NULL },
+	{ "local_unsorted",   on_local_unsorted, 0,              NULL, NULL },
 	{ "local_copy",       on_local_copy,     DS_COPYABLE,    NULL, NULL },
 	{ "local_modify",     on_local_modify,   DS_MODIFYABLE,  NULL, NULL },
 	{ "local_watch",      on_local_watch,    DS_WATCHABLE,   NULL, NULL },


Modified: scope/src/menu.c
8 files changed, 3 insertions(+), 5 deletions(-)
===================================================================
@@ -441,14 +441,12 @@ static void on_popup_inspect(G_GNUC_UNUSED const MenuItem *menu_item)
 }
 
 #define DS_EVALUATE (DS_SENDABLE | DS_EXTRA_1)
-#define DS_WATCHABLE 0
-#define DS_INSPECTABLE DS_NOT_BUSY
 
 static MenuItem popup_menu_items[] =
 {
-	{ "popup_evaluate", on_popup_evaluate, DS_EVALUATE,  NULL, NULL },
-	{ "popup_watch",    on_popup_watch,    DS_WATCHABLE, NULL, NULL },
-	{ "popup_inspect",  on_popup_inspect,  DS_WATCHABLE, NULL, NULL },
+	{ "popup_evaluate", on_popup_evaluate, DS_EVALUATE, NULL, NULL },
+	{ "popup_watch",    on_popup_watch,    0,           NULL, NULL },
+	{ "popup_inspect",  on_popup_inspect,  DS_NOT_BUSY, NULL, NULL },
 	{ NULL, NULL, 0, NULL, NULL }
 };
 


Modified: scope/src/parse.c
4 files changed, 4 insertions(+), 0 deletions(-)
===================================================================
@@ -57,6 +57,7 @@ static void on_quiet_error(G_GNUC_UNUSED GArray *nodes)
 	{ "*stopped,",                    on_thread_stopped,       '\0', '\0', 0 },
 	{ "=thread-created,",             on_thread_created,       '\0', '\0', 0 },
 	{ "=thread-exited,",              on_thread_exited,        '\0', '\0', 0 },
+	{ "=thread-selected,id=\"",       on_thread_selected,      '\0', '\0', 1 },
 	{ "=thread-group-started,id=\"",  on_thread_group_started, '\0', '\0', 1 },
 	{ "=thread-group-exited,id=\"",   on_thread_group_exited,  '\0', '\0', 1 },
 	{ "=thread-group-added,id=\"",    on_thread_group_added,   '\0', '\0', 1 },
@@ -68,8 +69,11 @@ static void on_quiet_error(G_GNUC_UNUSED GArray *nodes)
 	{ "^done,wpt={",                  on_break_inserted,       '\0', '\0', 1 },
 	{ "^done,hw-awpt={",              on_break_inserted,       '\0', '\0', 1 },
 	{ "^done,hw-rwpt={",              on_break_inserted,       '\0', '\0', 1 },
+	{ "^done,threads=[",              on_thread_follow,        '2',  '\0', 1 },
 	{ "^done,threads=[",              on_thread_info,          '\0', '\0', 1 },
+	{ "^done,new-thread-id=\"",       on_thread_selected,      '\0', '\0', 1 },
 	{ "^done,BreakpointTable={",      on_break_list,           '\0', '\0', 1 },
+	{ "^done,frame={",                on_stack_follow,         '2',  '\0', 0 },
 	{ "^done,frame={",                on_thread_frame,         '4',  '\0', 0 },
 	{ "^done,stack=[",                on_stack_frames,         '*',  '\0', 1 },
 	{ "^done,stack-args=[",           on_stack_arguments,      '*',  '\0', 1 },


Modified: scope/src/program.c
2 files changed, 2 insertions(+), 0 deletions(-)
===================================================================
@@ -418,6 +418,7 @@ void program_init(void)
 	extern gboolean thread_select_on_running;
 	extern gboolean thread_select_on_stopped;
 	extern gboolean thread_select_on_exited;
+	extern gboolean thread_select_follow;
 
 	program_dialog = dialog_connect("program_dialog");
 	program_page_vbox = get_widget("program_page_vbox");
@@ -525,6 +526,7 @@ void program_init(void)
 	stash_group_add_boolean(group, &thread_select_on_running, "select_on_running", FALSE);
 	stash_group_add_boolean(group, &thread_select_on_stopped, "select_on_stopped", TRUE);
 	stash_group_add_boolean(group, &thread_select_on_exited, "select_on_exited", TRUE);
+	stash_group_add_boolean(group, &thread_select_follow, "select_follow", TRUE);
 	stash_group_add_boolean(group, &thread_show_group, "show_group", TRUE);
 	stash_group_add_boolean(group, &thread_show_core, "show_core", TRUE);
 	thread_group = group;


Modified: scope/src/scope.c
2 files changed, 1 insertions(+), 1 deletions(-)
===================================================================
@@ -32,7 +32,7 @@
 PLUGIN_VERSION_CHECK(215)
 
 PLUGIN_SET_TRANSLATABLE_INFO(LOCALEDIR, GETTEXT_PACKAGE, _("Scope Debugger"),
-	_("Simple GDB front-end."), "0.78" , "Dimitar Toshkov Zhekov <dimitar.zhekov at gmail.com>")
+	_("Simple GDB front-end."), "0.79" , "Dimitar Toshkov Zhekov <dimitar.zhekov at gmail.com>")
 
 /* Keybinding(s) */
 enum


Modified: scope/src/stack.c
85 files changed, 61 insertions(+), 24 deletions(-)
===================================================================
@@ -68,9 +68,7 @@ static void stack_node_location(const ParseNode *node, const char *fid)
 
 void on_stack_frames(GArray *nodes)
 {
-	const char *token = parse_grab_token(nodes);
-
-	if (!g_strcmp0(token, thread_id))
+	if (!g_strcmp0(parse_grab_token(nodes), thread_id))
 	{
 		char *fid = g_strdup(frame_id);
 
@@ -163,17 +161,34 @@ static void stack_node_arguments(const ParseNode *node, ArgsData *ad)
 
 void on_stack_arguments(GArray *nodes)
 {
-	gint column_id;
-	GtkSortType order;
-	ArgsData ad;
-
-	gtk_tree_sortable_get_sort_column_id(sortable, &column_id, &order);
-	ad.sorted = column_id == GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID ||
-		(column_id == STACK_ID && order == GTK_SORT_ASCENDING);
-	ad.valid = ad.sorted && gtk_tree_model_get_iter_first(model, &ad.iter);
-
 	if (!g_strcmp0(parse_grab_token(nodes), thread_id))
+	{
+		gint column_id;
+		GtkSortType order;
+		ArgsData ad;
+
+		gtk_tree_sortable_get_sort_column_id(sortable, &column_id, &order);
+		ad.sorted = column_id == GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID ||
+			(column_id == STACK_ID && order == GTK_SORT_ASCENDING);
+		ad.valid = ad.sorted && gtk_tree_model_get_iter_first(model, &ad.iter);
 		array_foreach(parse_lead_array(nodes), (GFunc) stack_node_arguments, &ad);
+	}
+}
+
+void on_stack_follow(GArray *nodes)
+{
+	if (!g_strcmp0(parse_grab_token(nodes), thread_id))
+	{
+		const char *id = parse_find_value(parse_lead_array(nodes), "level");
+
+		iff (id, "no level")
+		{
+			GtkTreeIter iter;
+
+			iff (model_find(model, &iter, STACK_ID, id), "%s: level not found", id)
+				gtk_tree_selection_select_iter(selection, &iter);
+		}
+	}
 }
 
 gboolean stack_entry(void)
@@ -227,6 +242,16 @@ static void on_stack_refresh(G_GNUC_UNUSED const MenuItem *menu_item)
 	stack_send_update('2');
 }
 
+static void on_stack_synchronize(const MenuItem *menu_item)
+{
+	if (menu_item)
+		thread_query_frame('2');
+	else if (frame_id)
+		debug_send_format(T, "-stack-select-frame %s", frame_id);
+	else
+		plugin_blink();
+}
+
 static void on_stack_unsorted(G_GNUC_UNUSED const MenuItem *menu_item)
 {
 	gtk_tree_sortable_set_sort_column_id(sortable, GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID,
@@ -279,30 +304,33 @@ static void on_stack_show_entry(const MenuItem *menu_item)
 		debug_send_format(T, "04%s-stack-list-arguments 1", thread_id);
 }
 
-#define DS_FRESHABLE (DS_DEBUG | DS_EXTRA_1)
-#define DS_ENTRABLE (DS_ACTIVE | DS_EXTRA_2)
-#define DS_VIEWABLE (DS_ACTIVE | DS_EXTRA_3)
+#define DS_VIEWABLE (DS_ACTIVE | DS_EXTRA_2)
+#define DS_ENTRABLE (DS_ACTIVE | DS_EXTRA_3)
 
 static MenuItem stack_menu_items[] =
 {
-	{ "stack_refresh",      on_stack_refresh,      DS_FRESHABLE, NULL, NULL },
-	{ "stack_unsorted",     on_stack_unsorted,     DS_SORTABLE,  NULL, NULL },
-	{ "stack_view_source",  on_stack_view_source,  DS_VIEWABLE,  NULL, NULL },
-	{ "stack_show_entry",   on_stack_show_entry,   DS_ENTRABLE,  NULL, NULL },
-	{ "stack_show_address", on_stack_show_address, 0,            NULL, &stack_show_address },
+	{ "stack_refresh",      on_stack_refresh,      DS_DEBUG,    NULL, NULL },
+	{ "stack_unsorted",     on_stack_unsorted,     0,           NULL, NULL },
+	{ "stack_view_source",  on_stack_view_source,  DS_VIEWABLE, NULL, NULL },
+	{ "stack_synchronize",  on_stack_synchronize,  DS_DEBUG,    NULL, NULL },
+	{ "stack_show_entry",   on_stack_show_entry,   DS_ENTRABLE, NULL, NULL },
+	{ "stack_show_address", on_stack_show_address, 0,           NULL, &stack_show_address },
 	{ NULL, NULL, 0, NULL, NULL }
 };
 
 static guint stack_menu_extra_state(void)
 {
 	GtkTreeIter iter;
-	const char *func = NULL;
 
 	if (gtk_tree_selection_get_selected(selection, NULL, &iter))
-		gtk_tree_model_get(model, &iter, STACK_FUNC, &func, -1);
+	{
+		const char *file, *func;
+
+		gtk_tree_model_get(model, &iter, STACK_FILE, &file, STACK_FUNC, &func, -1);
+		return ((file != NULL) << DS_INDEX_2) | ((func != NULL) << DS_INDEX_3);
+	}
 
-	return ((thread_id != NULL) << DS_INDEX_1) | ((func != NULL) << DS_INDEX_2) |
-		((frame_id != NULL) << DS_INDEX_3);
+	return 0;
 }
 
 static MenuInfo stack_menu_info = { stack_menu_items, stack_menu_extra_state, 0 };
@@ -320,6 +348,12 @@ static void on_stack_menu_show(G_GNUC_UNUSED GtkWidget *widget, const MenuItem *
 	menu_item_set_active(menu_item + 1, stack_show_address);
 }
 
+static void on_stack_synchronize_button_release(GtkWidget *widget, GdkEventButton *event,
+	GtkWidget *menu)
+{
+	menu_shift_button_release(widget, event, menu, on_stack_synchronize);
+}
+
 void stack_init(void)
 {
 	GtkTreeView *tree = view_create("stack_view", &model, &selection);
@@ -339,6 +373,9 @@ void stack_init(void)
 	g_signal_connect(tree, "button-press-event", G_CALLBACK(on_view_button_1_press),
 		stack_seek_selected);
 	g_signal_connect(selection, "changed", G_CALLBACK(on_stack_selection_changed), NULL);
+
 	g_signal_connect(menu, "show", G_CALLBACK(on_stack_menu_show),
 		(gpointer) menu_item_find(stack_menu_items, "stack_show_entry"));
+	g_signal_connect(get_widget("stack_synchronize"), "button-release-event",
+		G_CALLBACK(on_stack_synchronize_button_release), menu);
 }


Modified: scope/src/stack.h
1 files changed, 1 insertions(+), 0 deletions(-)
===================================================================
@@ -23,6 +23,7 @@
 
 void on_stack_frames(GArray *nodes);
 void on_stack_arguments(GArray *nodes);
+void on_stack_follow(GArray *nodes);
 
 gboolean stack_entry(void);
 void stack_clear(void);


Modified: scope/src/thread.c
112 files changed, 96 insertions(+), 16 deletions(-)
===================================================================
@@ -28,6 +28,7 @@
 #include <signal.h>
 #else
 #define WINVER 0x0501
+#include <limits.h>
 #include <windows.h>
 #endif
 
@@ -235,12 +236,10 @@ static void thread_iter_running(GtkTreeIter *iter, const char *tid)
 	}
 }
 
-/* select a stopped thread when the current thread becomes running */
 gboolean thread_select_on_running;
-/* select a thread when it stops (unless already at stopped thread) */
 gboolean thread_select_on_stopped;
-/* select a stopped thread when the current thread exits */
 gboolean thread_select_on_exited;
+gboolean thread_select_follow;
 
 void on_thread_running(GArray *nodes)
 {
@@ -421,6 +420,22 @@ void on_thread_stopped(GArray *nodes)
 		view_dirty(VIEW_BREAKS);
 }
 
+static char *gdb_thread = NULL;
+
+static void set_gdb_thread(const char *tid, gboolean select)
+{
+	g_free(gdb_thread);
+	gdb_thread = g_strdup(tid);
+
+	if (select)
+	{
+		GtkTreeIter iter;
+
+		if (find_thread(gdb_thread, &iter))
+			gtk_tree_selection_select_iter(selection, &iter);
+	}
+}
+
 void on_thread_created(GArray *nodes)
 {
 	const char *tid = parse_find_value(nodes, "id");
@@ -454,6 +469,9 @@ void on_thread_created(GArray *nodes)
 			if (group && group->pid)
 				gtk_list_store_set(store, &iter, THREAD_PID, group->pid, -1);
 		}
+
+		if (thread_count == 1)
+			set_gdb_thread(tid, TRUE);
 	}
 }
 
@@ -465,6 +483,9 @@ void on_thread_exited(GArray *nodes)
 	{
 		GtkTreeIter iter;
 
+		if (!g_strcmp0(tid, gdb_thread))
+			set_gdb_thread(NULL, FALSE);
+		
 		if (find_thread(tid, &iter))
 		{
 			gboolean was_selected = !g_strcmp0(tid, thread_id);
@@ -490,6 +511,11 @@ void on_thread_exited(GArray *nodes)
 	}
 }
 
+void on_thread_selected(GArray *nodes)
+{
+	set_gdb_thread(parse_lead_value(nodes), thread_select_follow);
+}
+
 static void thread_parse(GArray *nodes, const char *tid, gboolean stopped)
 {
 	GtkTreeIter iter;
@@ -530,9 +556,27 @@ static void thread_node_parse(const ParseNode *node, G_GNUC_UNUSED gpointer gdat
 	}
 }
 
-void on_thread_info(GArray *nodes)
+static const char *thread_info_parse(GArray *nodes, gboolean select)
 {
+	const char *tid = parse_find_value(nodes, "current-thread-id");
+
 	array_foreach(parse_lead_array(nodes), (GFunc) thread_node_parse, NULL);
+
+	if (tid)
+		set_gdb_thread(tid, select);
+
+	return tid;
+}
+
+void on_thread_info(GArray *nodes)
+{
+	thread_info_parse(nodes, thread_select_follow);
+}
+
+void on_thread_follow(GArray *nodes)
+{
+	if (!thread_info_parse(nodes, TRUE))
+		dc_error("no current tid");
 }
 
 void on_thread_frame(GArray *nodes)
@@ -562,6 +606,7 @@ void threads_clear(void)
 	model_foreach(model, (GFunc) thread_iter_unmark, GINT_TO_POINTER(TRUE));
 	array_clear(thread_groups, (GFreeFunc) thread_group_free);
 	gtk_list_store_clear(store);
+	set_gdb_thread(NULL, FALSE);
 	thread_count = 0;
 }
 
@@ -590,6 +635,17 @@ gboolean threads_update(void)
 	return TRUE;
 }
 
+void thread_query_frame(char token)
+{
+	debug_send_format(T, "0%c%s-stack-info-frame", token, thread_id);
+}
+
+void thread_synchronize(void)
+{
+	if (thread_id && g_strcmp0(thread_id, gdb_thread))
+		debug_send_format(N, "04-thread-select %s", thread_id);
+}
+
 static void on_thread_selection_changed(GtkTreeSelection *selection,
 	G_GNUC_UNUSED gpointer gdata)
 {
@@ -621,7 +677,7 @@ static void on_thread_selection_changed(GtkTreeSelection *selection,
 			thread_state = THREAD_STOPPED;
 
 			if (debug_state() & DS_DEBUG)
-				thread_query_frame();
+				thread_query_frame('4');
 			else
 				thread_state = THREAD_QUERY_FRAME;
 		}
@@ -661,6 +717,16 @@ static void on_thread_view_source(G_GNUC_UNUSED const MenuItem *menu_item)
 	thread_seek_selected(FALSE);
 }
 
+static void on_thread_synchronize(const MenuItem *menu_item)
+{
+	if (menu_item)
+		debug_send_command(N, "02-thread-info");
+	else if (thread_id)
+		debug_send_format(N, "-thread-select %s", thread_id);
+	else
+		plugin_blink();
+}
+
 #ifdef G_OS_UNIX
 static void send_signal(int sig)
 {
@@ -696,11 +762,13 @@ static void on_thread_send_signal(G_GNUC_UNUSED const MenuItem *menu_item)
 {
 	gdouble value = 1;
 
-	if (dialogs_show_input_numeric(_("Send Signal"), _("Enter signal #:"), &value, 1, NSIG, 1))
+	if (dialogs_show_input_numeric(_("Send Signal"), _("Enter signal #:"), &value, 1, NSIG,
+		1))
+	{
 		send_signal(value);
+	}
 }
 #else  /* G_OS_UNIX */
-
 static HANDLE iter_to_handle(GtkTreeIter *iter)
 {
 	const char *pid;
@@ -735,7 +803,7 @@ static void on_thread_terminate(G_GNUC_UNUSED const MenuItem *menu_item)
 	gdouble value = 1;
 
 	if (dialogs_show_input_numeric(_("Terminate Process"), _("Enter exit code:"), &value, 1,
-		NSIG, 1))
+		UINT_MAX, 1))
 	{
 		GtkTreeIter iter;
 
@@ -772,25 +840,27 @@ static void on_thread_show_core(const MenuItem *menu_item)
 	view_column_set_visible("thread_core_column", thread_show_core);
 }
 
-#define DS_INTRABLE (DS_ACTIVE | DS_EXTRA_2)
-#define DS_TERMABLE (DS_ACTIVE | DS_EXTRA_2)
-#define DS_SIGNABLE (DS_ACTIVE | DS_EXTRA_2)
-#define DS_VIEWABLE (DS_ACTIVE | DS_EXTRA_3)
+#define DS_VIEWABLE (DS_ACTIVE | DS_EXTRA_2)
+#define DS_INTRABLE (DS_ACTIVE | DS_EXTRA_3)
+#define DS_TERMABLE (DS_ACTIVE | DS_EXTRA_3)
+#define DS_SIGNABLE (DS_ACTIVE | DS_EXTRA_3)
 
 static MenuItem thread_menu_items[] =
 {
 	{ "thread_refresh",           on_thread_refresh,        DS_SENDABLE, NULL, NULL },
-	{ "thread_unsorted",          on_thread_unsorted,       DS_SORTABLE, NULL, NULL },
+	{ "thread_unsorted",          on_thread_unsorted,       0,           NULL, NULL },
 	{ "thread_view_source",       on_thread_view_source,    DS_VIEWABLE, NULL, NULL },
+	{ "thread_synchronize",       on_thread_synchronize,    DS_SENDABLE, NULL, NULL },
 	{ "thread_interrupt",         on_thread_interrupt,      DS_INTRABLE, NULL, NULL },
 	{ "thread_terminate",         on_thread_terminate,      DS_TERMABLE, NULL, NULL },
 #ifdef G_OS_UNIX
 	{ "thread_send_signal",       on_thread_send_signal,    DS_SIGNABLE, NULL, NULL },
 #endif
-	{ "thread_auto_select",       on_menu_display_booleans, 0, NULL, GINT_TO_POINTER(3) },
+	{ "thread_auto_select",       on_menu_display_booleans, 0, NULL, GINT_TO_POINTER(4) },
 	{ "thread_select_on_running", on_menu_update_boolean, 0, NULL, &thread_select_on_running },
 	{ "thread_select_on_stopped", on_menu_update_boolean, 0, NULL, &thread_select_on_stopped },
 	{ "thread_select_on_exited",  on_menu_update_boolean, 0, NULL, &thread_select_on_exited },
+	{ "thread_select_follow",     on_menu_update_boolean, 0, NULL, &thread_select_follow },
 	{ "thread_show_columns",      on_menu_display_booleans, 0, NULL, GINT_TO_POINTER(2) },
 	{ "thread_show_group",        on_thread_show_group,   0, NULL, &thread_show_group },
 	{ "thread_show_core",         on_thread_show_core,    0, NULL, &thread_show_core },
@@ -806,7 +876,7 @@ static guint thread_menu_extra_state(void)
 		const char *pid, *file;
 
 		gtk_tree_model_get(model, &iter, THREAD_PID, &pid, THREAD_FILE, &file, -1);
-		return ((pid && atoi(pid) > 0) << DS_INDEX_2) | ((file != NULL) << DS_INDEX_3);
+		return ((file != NULL) << DS_INDEX_2) | ((utils_atoi0(pid) > 0) << DS_INDEX_3);
 	}
 
 	return 0;
@@ -814,9 +884,16 @@ static guint thread_menu_extra_state(void)
 
 static MenuInfo thread_menu_info = { thread_menu_items, thread_menu_extra_state, 0 };
 
+static void on_thread_synchronize_button_release(GtkWidget *widget, GdkEventButton *event,
+	GtkWidget *menu)
+{
+	menu_shift_button_release(widget, event, menu, on_thread_synchronize);
+}
+
 void thread_init(void)
 {
 	GtkTreeView *tree = view_create("thread_view", &model, &selection);
+	GtkWidget *menu = menu_select("thread_menu", &thread_menu_info, selection);
 
 	store = GTK_LIST_STORE(model);
 	sortable = GTK_TREE_SORTABLE(model);
@@ -837,8 +914,10 @@ void thread_init(void)
 		thread_seek_selected);
 	g_signal_connect(tree, "button-press-event", G_CALLBACK(on_view_button_1_press),
 		thread_seek_selected);
+
 	g_signal_connect(selection, "changed", G_CALLBACK(on_thread_selection_changed), NULL);
-	menu_select("thread_menu", &thread_menu_info, selection);
+	g_signal_connect(get_widget("thread_synchronize"), "button-release-event",
+		G_CALLBACK(on_thread_synchronize_button_release), menu);
 #ifndef G_OS_UNIX
 	gtk_widget_hide(get_widget("thread_send_signal"));
 #endif
@@ -848,4 +927,5 @@ void thread_finalize(void)
 {
 	model_foreach(model, (GFunc) thread_iter_unmark, NULL);
 	array_free(thread_groups, (GFreeFunc) thread_group_free);
+	set_gdb_thread(NULL, FALSE);
 }


Modified: scope/src/thread.h
8 files changed, 5 insertions(+), 3 deletions(-)
===================================================================
@@ -42,16 +42,18 @@
 void on_thread_stopped(GArray *nodes);
 void on_thread_created(GArray *nodes);
 void on_thread_exited(GArray *nodes);
+void on_thread_selected(GArray *nodes);
 void on_thread_info(GArray *nodes);
+void on_thread_follow(GArray *nodes);
 void on_thread_frame(GArray *nodes);
 
 void threads_mark(GeanyDocument *doc);
 void threads_clear(void);
 void threads_delta(ScintillaObject *sci, const char *real_path, gint start, gint delta);
-
 gboolean threads_update(void);
-#define thread_query_frame() \
-	debug_send_format(T, "04%s-stack-info-frame", thread_id)
+
+void thread_query_frame(char token);
+void thread_synchronize(void);
 
 void thread_init(void);
 void thread_finalize(void);


Modified: scope/src/views.c
6 files changed, 3 insertions(+), 3 deletions(-)
===================================================================
@@ -98,7 +98,7 @@ void views_update(DebugState state)
 		if (thread_state == THREAD_QUERY_FRAME)
 		{
 			if (!views[VIEW_THREADS].dirty)
-				thread_query_frame();
+				thread_query_frame('4');
 
 			thread_state = THREAD_STOPPED;
 		}
@@ -119,7 +119,7 @@ void views_update(DebugState state)
 		if (thread_state == THREAD_QUERY_FRAME)
 		{
 			if (view_current != VIEW_THREADS || !views[VIEW_THREADS].dirty)
-				thread_query_frame();
+				thread_query_frame('4');
 
 			thread_state = THREAD_STOPPED;
 		}
@@ -437,7 +437,6 @@ static void on_command_insert_button_clicked(G_GNUC_UNUSED GtkButton *button, gp
 	gtk_text_buffer_insert_at_cursor(command_text, text->str, -1);
 	g_string_free(text, TRUE);
 	gtk_widget_grab_focus(command_view);
-
 }
 
 static void on_command_send_button_clicked(G_GNUC_UNUSED GtkButton *button,
@@ -447,6 +446,7 @@ static void on_command_send_button_clicked(G_GNUC_UNUSED GtkButton *button,
 	const gchar *start;
 	char *locale;
 
+	thread_synchronize();
 	utils_str_replace_all(&text, "\n", " ");
 	start = utils_skip_spaces(text);
 	locale = gtk_toggle_button_get_active(command_locale) ?


Modified: scope/src/views.h
2 files changed, 0 insertions(+), 2 deletions(-)
===================================================================
@@ -34,8 +34,6 @@
 	VIEW_COUNT
 } ViewIndex;
 
-#define DS_SORTABLE 0
-
 void view_dirty(ViewIndex index);
 void views_clear(void);
 void views_update(DebugState state);


Modified: scope/src/watch.c
8 files changed, 3 insertions(+), 5 deletions(-)
===================================================================
@@ -353,8 +353,6 @@ static void on_watch_delete(G_GNUC_UNUSED const MenuItem *menu_item)
 	}
 }
 
-#define DS_FRESHABLE DS_SENDABLE
-#define DS_WATCHABLE 0
 #define DS_COPYABLE (DS_BASICS | DS_EXTRA_1)
 #define DS_MODIFYABLE (DS_SENDABLE | DS_EXTRA_1)
 #define DS_INSPECTABLE (DS_NOT_BUSY | DS_EXTRA_1)
@@ -363,9 +361,9 @@ static void on_watch_delete(G_GNUC_UNUSED const MenuItem *menu_item)
 
 static MenuItem watch_menu_items[] =
 {
-	{ "watch_refresh",    on_watch_refresh,  DS_FRESHABLE,   NULL, NULL },
-	{ "watch_unsorted",   on_watch_unsorted, DS_SORTABLE,    NULL, NULL },
-	{ "watch_add",        on_watch_add,      DS_WATCHABLE,   NULL, NULL },
+	{ "watch_refresh",    on_watch_refresh,  DS_SENDABLE,    NULL, NULL },
+	{ "watch_unsorted",   on_watch_unsorted, 0,              NULL, NULL },
+	{ "watch_add",        on_watch_add,      0,              NULL, NULL },
 	{ "watch_copy",       on_watch_copy,     DS_COPYABLE,    NULL, NULL },
 	{ "watch_modify",     on_watch_modify,   DS_MODIFYABLE,  NULL, NULL },
 	{ "watch_inspect",    on_watch_inspect,  DS_INSPECTABLE, NULL, NULL },



--------------
This E-Mail was brought to you by github_commit_mail.py (Source: TBD).


More information about the Plugins-Commits mailing list