Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* [RFC] Implement =thread-selected notification.
@ 2008-11-12 23:20 Vladimir Prus
  2008-11-13  5:08 ` Eli Zaretskii
  2008-11-13  8:54 ` Pedro Alves
  0 siblings, 2 replies; 7+ messages in thread
From: Vladimir Prus @ 2008-11-12 23:20 UTC (permalink / raw)
  To: gdb-patches


This patch implements =thread-selected notification, needed so that if user
types "thread N" in GDB console of a frontend, frontend can understand that
user wants to see a different thread.

Is the interps.{c,h} change OK?

Eli, is the doc patch fine with you?

- Volodya

From a760fdf6dd4b68ab8c5c64a0066b4d79e584a693 Mon Sep 17 00:00:00 2001

	[doc/ChangeLog]
	* gdb.texinfo (GDB/MI Async Records): Document
	=thread-selected.

	[ChangeLog]
	* interps.c (top_level_interpreter_name): New.
	* interps.h (top_level_interpreter_name): Declare.
	* mi/mi-common.h (struct mi_interp): New, moved from ...
	* mi/mi-interp.c: ...here.
	* mi/mi-main.c (mi_execute_command): If the thread changed
	as result of command, report that.

	[testsuite/ChangeLog]
	* gdb.mi/mi-pthreads.exp (check_mi_thread_command_set): Make sure
	"thread N" results in =thread-selected.
	* lib/mi-support (mi_run_cmd, mi_expect_stop)
	(mi_send_resuming_command_raw, mi_get_stop_line): Be prepared for
	=thread-selected.
---
 gdb/doc/gdb.texinfo                  |   13 +++++++++++++
 gdb/interps.c                        |    7 +++++++
 gdb/interps.h                        |    1 +
 gdb/mi/mi-common.h                   |   15 +++++++++++++++
 gdb/mi/mi-interp.c                   |   16 +---------------
 gdb/mi/mi-main.c                     |   30 ++++++++++++++++++++++++++++++
 gdb/testsuite/gdb.mi/mi-pthreads.exp |    6 ++++++
 gdb/testsuite/lib/mi-support.exp     |   10 +++++-----
 8 files changed, 78 insertions(+), 20 deletions(-)

diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 261d1c7..ca8759d 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -19273,6 +19273,19 @@ A signal was received by the inferior.
 @itemx =thread-exited,id="@var{id}"
 A thread either was created, or has exited.  The @var{id} field
 contains the @value{GDBN} identifier of the thread.
+
+@item =thread-selected,id="@var{id}"
+Informs that the selected thread was changed as result of the last
+command.  This notification is not emitted as result of @code{-thread-select}
+command but is emitted whenever an MI command that is not documented
+to change the selected thread actually changes it.  In particular,
+invoking, directly or indirectly (via user-defined command), the CLI
+@code{thread} command, will generate this notification.
+
+We suggest that in response to this notification, front ends
+highlight the selected thread and cause subsequent commands apply to
+that thread.
+
 @end table
 
 
diff --git a/gdb/interps.c b/gdb/interps.c
index 73bc51c..6f6232c 100644
--- a/gdb/interps.c
+++ b/gdb/interps.c
@@ -479,6 +479,13 @@ top_level_interpreter_data (void)
   return top_level_interpreter_ptr->data;  
 }
 
+const char *
+top_level_interpreter_name (void)
+{
+  gdb_assert (top_level_interpreter_ptr);
+  return top_level_interpreter_ptr->name;  
+}
+
 /* This just adds the "interpreter-exec" command.  */
 void
 _initialize_interpreter (void)
diff --git a/gdb/interps.h b/gdb/interps.h
index 353ed0a..e6aa57a 100644
--- a/gdb/interps.h
+++ b/gdb/interps.h
@@ -67,6 +67,7 @@ extern void current_interp_command_loop (void);
 /* Returns opaque data associated with the top-level interpreter.  */
 extern void *top_level_interpreter_data (void);
 extern struct interp *top_level_interpreter (void);
+extern const char *top_level_interpreter_name (void);
 
 extern void clear_interpreter_hooks (void);
 
diff --git a/gdb/mi/mi-common.h b/gdb/mi/mi-common.h
index e47afd1..8778e74 100644
--- a/gdb/mi/mi-common.h
+++ b/gdb/mi/mi-common.h
@@ -41,4 +41,19 @@ enum async_reply_reason
 
 const char *async_reason_lookup (enum async_reply_reason reason);
 
+struct mi_interp
+{
+  /* MI's output channels */
+  struct ui_file *out;
+  struct ui_file *err;
+  struct ui_file *log;
+  struct ui_file *targ;
+  struct ui_file *event_channel;
+
+  /* This is the interpreter for the mi... */
+  struct interp *mi2_interp;
+  struct interp *mi1_interp;
+  struct interp *mi_interp;
+};
+
 #endif
diff --git a/gdb/mi/mi-interp.c b/gdb/mi/mi-interp.c
index e05b1ad..5aa0e6c 100644
--- a/gdb/mi/mi-interp.c
+++ b/gdb/mi/mi-interp.c
@@ -31,24 +31,10 @@
 #include "mi-cmds.h"
 #include "mi-out.h"
 #include "mi-console.h"
+#include "mi-common.h"
 #include "observer.h"
 #include "gdbthread.h"
 
-struct mi_interp
-{
-  /* MI's output channels */
-  struct ui_file *out;
-  struct ui_file *err;
-  struct ui_file *log;
-  struct ui_file *targ;
-  struct ui_file *event_channel;
-
-  /* This is the interpreter for the mi... */
-  struct interp *mi2_interp;
-  struct interp *mi1_interp;
-  struct interp *mi_interp;
-};
-
 /* These are the interpreter setup, etc. functions for the MI interpreter */
 static void mi_execute_command_wrapper (char *cmd);
 static void mi_command_loop (int mi_version);
diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c
index bd149ef..a205395 100644
--- a/gdb/mi/mi-main.c
+++ b/gdb/mi/mi-main.c
@@ -44,6 +44,7 @@
 #include "gdb.h"
 #include "frame.h"
 #include "mi-main.h"
+#include "mi-common.h"
 #include "language.h"
 #include "valprint.h"
 #include "inferior.h"
@@ -1167,6 +1168,9 @@ mi_execute_command (char *cmd, int from_tty)
   if (command != NULL)
     {
       struct gdb_exception result;
+      ptid_t previous_ptid = inferior_ptid;
+      int had_execution = target_has_execution;
+      const char *top_name;
 
       if (do_timings)
 	{
@@ -1191,6 +1195,32 @@ mi_execute_command (char *cmd, int from_tty)
 	  mi_out_rewind (uiout);
 	}
 
+      /* The notifications are only output when the top-level
+	 interpreter (specified on the command line) is MI.  */      
+      top_name = top_level_interpreter_name ();
+      if (had_execution && target_has_execution 
+	  && strstr (top_name, "mi") == top_name)
+	{
+	  struct mi_interp *mi = top_level_interpreter_data ();
+	  if (!ptid_equal (previous_ptid, null_ptid)
+	      && !ptid_equal (inferior_ptid, previous_ptid))
+	    {
+	      /* If there are no threads in thread table, we cannot report
+		 anything.  */
+	      if (strcmp (command->command, "thread-select") != 0
+		  && thread_count () != 0)
+		{
+		  struct thread_info *ti = find_thread_pid (inferior_ptid);
+		  gdb_assert (ti);	      
+		  target_terminal_ours ();
+		  fprintf_unfiltered (mi->event_channel, 
+				      "thread-selected,id=\"%d\"",
+				      ti->num);
+		  gdb_flush (mi->event_channel);
+		}
+	    }
+	}
+
       mi_parse_free (command);
     }
 
diff --git a/gdb/testsuite/gdb.mi/mi-pthreads.exp b/gdb/testsuite/gdb.mi/mi-pthreads.exp
index dbb3ece..0ab5715 100644
--- a/gdb/testsuite/gdb.mi/mi-pthreads.exp
+++ b/gdb/testsuite/gdb.mi/mi-pthreads.exp
@@ -55,6 +55,12 @@ proc check_mi_thread_command_set {} {
       "\\^done,new-thread-id=\"$thread\",frame={.*}(,line=\"(-)?\[0-9\]+\",file=\".*\")?" \
       "check_mi_thread_command_set: -thread-select $thread"
   }
+
+  foreach thread $thread_list {
+      mi_gdb_test "-interpreter-exec console \"thread $thread\"" \
+          ".*\\^done\r\n=thread-selected,id=\"$thread\"" \
+          "check =thread-selected: thread $thread"
+  }
 }
 
 #
diff --git a/gdb/testsuite/lib/mi-support.exp b/gdb/testsuite/lib/mi-support.exp
index 9ef9df9..f29ecd4 100644
--- a/gdb/testsuite/lib/mi-support.exp
+++ b/gdb/testsuite/lib/mi-support.exp
@@ -816,7 +816,7 @@ proc mi_run_cmd {args} {
 
     send_gdb "220-exec-run $args\n"
     gdb_expect {
-	-re "220\\^running\r\n(\\*running,thread-id=\"\[^\"\]+\"\r\n|=thread-created,id=\"1\"\r\n)*${mi_gdb_prompt}" {
+	-re "220\\^running\r\n(\\*running,thread-id=\"\[^\"\]+\"\r\n|=thread-created,id=\"1\"\r\n)*(=thread-selected,id=\".*\"\r\n)?${mi_gdb_prompt}" {
 	}
 	timeout {
 	    perror "Unable to start target"
@@ -1014,9 +1014,9 @@ proc mi_expect_stop { reason func args file line extra test } {
 
     set any "\[^\n\]*"
 
-    verbose -log "mi_expect_stop: expecting: \\*stopped,${r}${a}${bn}thread-id=\"$decimal\",stopped-threads=$any,frame=\{addr=\"$hex\",func=\"$func\",args=$args,file=\"$any$file\",fullname=\"${fullname_syntax}$file\",line=\"$line\"\}\r\n$after_stopped$prompt_re"
+    verbose -log "mi_expect_stop: expecting: \\*stopped,${r}${a}${bn}thread-id=\"$decimal\",stopped-threads=$any,frame=\{addr=\"$hex\",func=\"$func\",args=$args,file=\"$any$file\",fullname=\"${fullname_syntax}$file\",line=\"$line\"\}\r\n$after_stopped(=thread-selected,id=\".*\"\r\n)?$prompt_re"
     gdb_expect {
-	-re "\\*stopped,${r}${a}${bn}thread-id=\"$decimal\",stopped-threads=$any,frame=\{addr=\"$hex\",func=\"$func\",args=$args,file=\"$any$file\",fullname=\"${fullname_syntax}$file\",line=\"($line)\"\}$after_stopped\r\n$prompt_re" {
+	-re "\\*stopped,${r}${a}${bn}thread-id=\"$decimal\",stopped-threads=$any,frame=\{addr=\"$hex\",func=\"$func\",args=$args,file=\"$any$file\",fullname=\"${fullname_syntax}$file\",line=\"($line)\"\}$after_stopped\r\n(=thread-selected,id=\".*\"\r\n)?$prompt_re" {
 	    pass "$test"
             return $expect_out(2,string)
 	}
@@ -1433,7 +1433,7 @@ proc mi_send_resuming_command_raw {command test} {
 
     send_gdb "$command\n"
     gdb_expect {
-        -re "\\^running\r\n\\*running,thread-id=\"\[^\"\]+\"\r\n${mi_gdb_prompt}" {
+        -re "\\^running\r\n\\*running,thread-id=\"\[^\"\]+\"\r\n(=thread-selected,id=\".*\"\r\n)?${mi_gdb_prompt}" {
             # Note that lack of 'pass' call here -- this works around limitation
             # in DejaGNU xfail mechanism. mi-until.exp has this:
             #
@@ -1491,7 +1491,7 @@ proc mi_get_stop_line {test} {
   }
 
   gdb_expect {
-      -re ".*line=\"(\[0-9\]*)\".*\r\n$prompt_re" {
+      -re ".*line=\"(\[0-9\]*)\".*\r\n(=thread-selected,id=\".*\"\r\n)?$prompt_re" {
           return $expect_out(1,string)
       }
       -re ".*$mi_gdb_prompt" {
-- 
1.5.3.5


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [RFC] Implement =thread-selected notification.
  2008-11-12 23:20 [RFC] Implement =thread-selected notification Vladimir Prus
@ 2008-11-13  5:08 ` Eli Zaretskii
  2008-11-13  8:54 ` Pedro Alves
  1 sibling, 0 replies; 7+ messages in thread
From: Eli Zaretskii @ 2008-11-13  5:08 UTC (permalink / raw)
  To: Vladimir Prus; +Cc: gdb-patches

> From: Vladimir Prus <vladimir@codesourcery.com>
> Date: Wed, 12 Nov 2008 23:43:24 +0300
> 
> 
> This patch implements =thread-selected notification, needed so that if user
> types "thread N" in GDB console of a frontend, frontend can understand that
> user wants to see a different thread.
> 
> Is the interps.{c,h} change OK?
> 
> Eli, is the doc patch fine with you?

Yes, thanks.


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [RFC] Implement =thread-selected notification.
  2008-11-12 23:20 [RFC] Implement =thread-selected notification Vladimir Prus
  2008-11-13  5:08 ` Eli Zaretskii
@ 2008-11-13  8:54 ` Pedro Alves
  2008-11-13 11:26   ` Pedro Alves
  2008-11-13 15:53   ` Vladimir Prus
  1 sibling, 2 replies; 7+ messages in thread
From: Pedro Alves @ 2008-11-13  8:54 UTC (permalink / raw)
  To: gdb-patches; +Cc: Vladimir Prus, gdb-patches

On Wednesday 12 November 2008 20:43:24, Vladimir Prus wrote:

>  
> +const char *
> +top_level_interpreter_name (void)
> +{
> +  gdb_assert (top_level_interpreter_ptr);
> +  return top_level_interpreter_ptr->name;  
> +}
> +
>  /* This just adds the "interpreter-exec" command.  */
>  void
>  _initialize_interpreter (void)
> diff --git a/gdb/interps.h b/gdb/interps.h
> index 353ed0a..e6aa57a 100644
> --- a/gdb/interps.h
> +++ b/gdb/interps.h
> @@ -67,6 +67,7 @@ extern void current_interp_command_loop (void);
>  /* Returns opaque data associated with the top-level interpreter.  */
>  extern void *top_level_interpreter_data (void);
>  extern struct interp *top_level_interpreter (void);
> +extern const char *top_level_interpreter_name (void);
>  
>  extern void clear_interpreter_hooks (void);
>  
> diff --git a/gdb/mi/mi-common.h b/gdb/mi/mi-common.h
> index e47afd1..8778e74 100644
> --- a/gdb/mi/mi-common.h
> +++ b/gdb/mi/mi-common.h
> @@ -41,4 +41,19 @@ enum async_reply_reason
>  
>  const char *async_reason_lookup (enum async_reply_reason reason);
>  
> +struct mi_interp
> +{
> +  /* MI's output channels */
> +  struct ui_file *out;
> +  struct ui_file *err;
> +  struct ui_file *log;
> +  struct ui_file *targ;
> +  struct ui_file *event_channel;
> +
> +  /* This is the interpreter for the mi... */
> +  struct interp *mi2_interp;
> +  struct interp *mi1_interp;
> +  struct interp *mi_interp;
> +};
> +
>  #endif
> diff --git a/gdb/mi/mi-interp.c b/gdb/mi/mi-interp.c
> index e05b1ad..5aa0e6c 100644
> --- a/gdb/mi/mi-interp.c
> +++ b/gdb/mi/mi-interp.c
> @@ -31,24 +31,10 @@
>  #include "mi-cmds.h"
>  #include "mi-out.h"
>  #include "mi-console.h"
> +#include "mi-common.h"
>  #include "observer.h"
>  #include "gdbthread.h"
>  
> -struct mi_interp
> -{
> -  /* MI's output channels */
> -  struct ui_file *out;
> -  struct ui_file *err;
> -  struct ui_file *log;
> -  struct ui_file *targ;
> -  struct ui_file *event_channel;
> -
> -  /* This is the interpreter for the mi... */
> -  struct interp *mi2_interp;
> -  struct interp *mi1_interp;
> -  struct interp *mi_interp;
> -};
> -
>  /* These are the interpreter setup, etc. functions for the MI interpreter */
>  static void mi_execute_command_wrapper (char *cmd);
>  static void mi_command_loop (int mi_version);
> diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c
> index bd149ef..a205395 100644
> --- a/gdb/mi/mi-main.c
> +++ b/gdb/mi/mi-main.c
> @@ -44,6 +44,7 @@
>  #include "gdb.h"
>  #include "frame.h"
>  #include "mi-main.h"
> +#include "mi-common.h"
>  #include "language.h"
>  #include "valprint.h"
>  #include "inferior.h"
> @@ -1167,6 +1168,9 @@ mi_execute_command (char *cmd, int from_tty)
>    if (command != NULL)
>      {
>        struct gdb_exception result;
> +      ptid_t previous_ptid = inferior_ptid;
> +      int had_execution = target_has_execution;
> +      const char *top_name;
>  
>        if (do_timings)
>  	{
> @@ -1191,6 +1195,32 @@ mi_execute_command (char *cmd, int from_tty)
>  	  mi_out_rewind (uiout);
>  	}
>  

> +      /* The notifications are only output when the top-level
> +	 interpreter (specified on the command line) is MI.  */      
> +      top_name = top_level_interpreter_name ();
> +      if (had_execution && target_has_execution 

> +	  && strstr (top_name, "mi") == top_name)

Why not,

 ui_out_is_mi_like_p (interp_ui_out (top_level_interpreter ())))

instead of relying on the interpreter name?

> +	{
> +	  struct mi_interp *mi = top_level_interpreter_data ();
> +	  if (!ptid_equal (previous_ptid, null_ptid)
> +	      && !ptid_equal (inferior_ptid, previous_ptid))
> +	    {

Checking for target_has_execution means that these new
notifications will not be emitted when using the "thread" command while debugging
a multi-threaded core file.

> +	      /* If there are no threads in thread table, we cannot report
> +		 anything.  */
> +	      if (strcmp (command->command, "thread-select") != 0
> +		  && thread_count () != 0)
> +		{

> +		  struct thread_info *ti = find_thread_pid (inferior_ptid);
> +		  gdb_assert (ti);	      

 These two lines can be replaced by 'struct thread_info *t = inferior_thread ()'.

> +		  target_terminal_ours ();
> +		  fprintf_unfiltered (mi->event_channel, 
> +				      "thread-selected,id=\"%d\"",
> +				      ti->num);
> +		  gdb_flush (mi->event_channel);
> +		}
> +	    }
> +	}
> +
>        mi_parse_free (command);
>      }
>  
> diff --git a/gdb/testsuite/gdb.mi/mi-pthreads.exp b/gdb/testsuite/gdb.mi/mi-pthreads.exp
> index dbb3ece..0ab5715 100644
> --- a/gdb/testsuite/gdb.mi/mi-pthreads.exp
> +++ b/gdb/testsuite/gdb.mi/mi-pthreads.exp
> @@ -55,6 +55,12 @@ proc check_mi_thread_command_set {} {
>        "\\^done,new-thread-id=\"$thread\",frame={.*}(,line=\"(-)?\[0-9\]+\",file=\".*\")?" \
>        "check_mi_thread_command_set: -thread-select $thread"
>    }
> +
> +  foreach thread $thread_list {
> +      mi_gdb_test "-interpreter-exec console \"thread $thread\"" \
> +          ".*\\^done\r\n=thread-selected,id=\"$thread\"" \
> +          "check =thread-selected: thread $thread"
> +  }
>  }
>  
>  #
> diff --git a/gdb/testsuite/lib/mi-support.exp b/gdb/testsuite/lib/mi-support.exp
> index 9ef9df9..f29ecd4 100644
> --- a/gdb/testsuite/lib/mi-support.exp
> +++ b/gdb/testsuite/lib/mi-support.exp
> @@ -816,7 +816,7 @@ proc mi_run_cmd {args} {
>  
>      send_gdb "220-exec-run $args\n"
>      gdb_expect {
> -	-re "220\\^running\r\n(\\*running,thread-id=\"\[^\"\]+\"\r\n|=thread-created,id=\"1\"\r\n)*${mi_gdb_prompt}" {
> +	-re "220\\^running\r\n(\\*running,thread-id=\"\[^\"\]+\"\r\n|=thread-created,id=\"1\"\r\n)*(=thread-selected,id=\".*\"\r\n)?${mi_gdb_prompt}" {
                                                                                                                          ^
Could you please not use .* in the mi support files?  We've recently
been through removing those for non-stop, because they're
racy --- they'll often times eat too much, and it's a good practice
to not do it from the start.

>  	}
>  	timeout {
>  	    perror "Unable to start target"
> @@ -1014,9 +1014,9 @@ proc mi_expect_stop { reason func args file line extra test } {
>  
>      set any "\[^\n\]*"
>  
> -    verbose -log "mi_expect_stop: expecting: \\*stopped,${r}${a}${bn}thread-id=\"$decimal\",stopped-threads=$any,frame=\{addr=\"$hex\",func=\"$func\",args=$args,file=\"$any$file\",fullname=\"${fullname_syntax}$file\",line=\"$line\"\}\r\n$after_stopped$prompt_re"
> +    verbose -log "mi_expect_stop: expecting: \\*stopped,${r}${a}${bn}thread-id=\"$decimal\",stopped-threads=$any,frame=\{addr=\"$hex\",func=\"$func\",args=$args,file=\"$any$file\",fullname=\"${fullname_syntax}$file\",line=\"$line\"\}\r\n$after_stopped(=thread-selected,id=\".*\"\r\n)?$prompt_re"
>      gdb_expect {
> -	-re "\\*stopped,${r}${a}${bn}thread-id=\"$decimal\",stopped-threads=$any,frame=\{addr=\"$hex\",func=\"$func\",args=$args,file=\"$any$file\",fullname=\"${fullname_syntax}$file\",line=\"($line)\"\}$after_stopped\r\n$prompt_re" {
> +	-re "\\*stopped,${r}${a}${bn}thread-id=\"$decimal\",stopped-threads=$any,frame=\{addr=\"$hex\",func=\"$func\",args=$args,file=\"$any$file\",fullname=\"${fullname_syntax}$file\",line=\"($line)\"\}$after_stopped\r\n(=thread-selected,id=\".*\"\r\n)?$prompt_re" {
>  	    pass "$test"
>              return $expect_out(2,string)
>  	}
> @@ -1433,7 +1433,7 @@ proc mi_send_resuming_command_raw {command test} {
>  
>      send_gdb "$command\n"
>      gdb_expect {
> -        -re "\\^running\r\n\\*running,thread-id=\"\[^\"\]+\"\r\n${mi_gdb_prompt}" {
> +        -re "\\^running\r\n\\*running,thread-id=\"\[^\"\]+\"\r\n(=thread-selected,id=\".*\"\r\n)?${mi_gdb_prompt}" {

                                                                                          ^ 

Same here.

>              # Note that lack of 'pass' call here -- this works around limitation
>              # in DejaGNU xfail mechanism. mi-until.exp has this:
>              #
> @@ -1491,7 +1491,7 @@ proc mi_get_stop_line {test} {
>    }
>  
>    gdb_expect {
> -      -re ".*line=\"(\[0-9\]*)\".*\r\n$prompt_re" {
> +      -re ".*line=\"(\[0-9\]*)\".*\r\n(=thread-selected,id=\".*\"\r\n)?$prompt_re" {

                                                                ^ 
Same here.

>            return $expect_out(1,string)
>        }
>        -re ".*$mi_gdb_prompt" {
-- 
Pedro Alves


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [RFC] Implement =thread-selected notification.
  2008-11-13  8:54 ` Pedro Alves
@ 2008-11-13 11:26   ` Pedro Alves
  2008-11-13 15:53   ` Vladimir Prus
  1 sibling, 0 replies; 7+ messages in thread
From: Pedro Alves @ 2008-11-13 11:26 UTC (permalink / raw)
  To: gdb-patches; +Cc: Vladimir Prus, gdb-patches

On Wednesday 12 November 2008 20:43:24, Vladimir Prus wrote:

>  
> +const char *
> +top_level_interpreter_name (void)
> +{
> +  gdb_assert (top_level_interpreter_ptr);
> +  return top_level_interpreter_ptr->name;  
> +}
> +
>  /* This just adds the "interpreter-exec" command.  */
>  void
>  _initialize_interpreter (void)
> diff --git a/gdb/interps.h b/gdb/interps.h
> index 353ed0a..e6aa57a 100644
> --- a/gdb/interps.h
> +++ b/gdb/interps.h
> @@ -67,6 +67,7 @@ extern void current_interp_command_loop (void);
>  /* Returns opaque data associated with the top-level interpreter.  */
>  extern void *top_level_interpreter_data (void);
>  extern struct interp *top_level_interpreter (void);
> +extern const char *top_level_interpreter_name (void);
>  
>  extern void clear_interpreter_hooks (void);
>  
> diff --git a/gdb/mi/mi-common.h b/gdb/mi/mi-common.h
> index e47afd1..8778e74 100644
> --- a/gdb/mi/mi-common.h
> +++ b/gdb/mi/mi-common.h
> @@ -41,4 +41,19 @@ enum async_reply_reason
>  
>  const char *async_reason_lookup (enum async_reply_reason reason);
>  
> +struct mi_interp
> +{
> +  /* MI's output channels */
> +  struct ui_file *out;
> +  struct ui_file *err;
> +  struct ui_file *log;
> +  struct ui_file *targ;
> +  struct ui_file *event_channel;
> +
> +  /* This is the interpreter for the mi... */
> +  struct interp *mi2_interp;
> +  struct interp *mi1_interp;
> +  struct interp *mi_interp;
> +};
> +
>  #endif
> diff --git a/gdb/mi/mi-interp.c b/gdb/mi/mi-interp.c
> index e05b1ad..5aa0e6c 100644
> --- a/gdb/mi/mi-interp.c
> +++ b/gdb/mi/mi-interp.c
> @@ -31,24 +31,10 @@
>  #include "mi-cmds.h"
>  #include "mi-out.h"
>  #include "mi-console.h"
> +#include "mi-common.h"
>  #include "observer.h"
>  #include "gdbthread.h"
>  
> -struct mi_interp
> -{
> -  /* MI's output channels */
> -  struct ui_file *out;
> -  struct ui_file *err;
> -  struct ui_file *log;
> -  struct ui_file *targ;
> -  struct ui_file *event_channel;
> -
> -  /* This is the interpreter for the mi... */
> -  struct interp *mi2_interp;
> -  struct interp *mi1_interp;
> -  struct interp *mi_interp;
> -};
> -
>  /* These are the interpreter setup, etc. functions for the MI interpreter */
>  static void mi_execute_command_wrapper (char *cmd);
>  static void mi_command_loop (int mi_version);
> diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c
> index bd149ef..a205395 100644
> --- a/gdb/mi/mi-main.c
> +++ b/gdb/mi/mi-main.c
> @@ -44,6 +44,7 @@
>  #include "gdb.h"
>  #include "frame.h"
>  #include "mi-main.h"
> +#include "mi-common.h"
>  #include "language.h"
>  #include "valprint.h"
>  #include "inferior.h"
> @@ -1167,6 +1168,9 @@ mi_execute_command (char *cmd, int from_tty)
>    if (command != NULL)
>      {
>        struct gdb_exception result;
> +      ptid_t previous_ptid = inferior_ptid;
> +      int had_execution = target_has_execution;
> +      const char *top_name;
>  
>        if (do_timings)
>  	{
> @@ -1191,6 +1195,32 @@ mi_execute_command (char *cmd, int from_tty)
>  	  mi_out_rewind (uiout);
>  	}
>  

> +      /* The notifications are only output when the top-level
> +	 interpreter (specified on the command line) is MI.  */      
> +      top_name = top_level_interpreter_name ();
> +      if (had_execution && target_has_execution 

> +	  && strstr (top_name, "mi") == top_name)

Why not,

 ui_out_is_mi_like_p (interp_ui_out (top_level_interpreter ())))

instead of relying on the interpreter name?

> +	{
> +	  struct mi_interp *mi = top_level_interpreter_data ();
> +	  if (!ptid_equal (previous_ptid, null_ptid)
> +	      && !ptid_equal (inferior_ptid, previous_ptid))
> +	    {

Checking for target_has_execution means that these new
notifications will not be emitted when using the "thread" command while debugging
a multi-threaded core file.

> +	      /* If there are no threads in thread table, we cannot report
> +		 anything.  */
> +	      if (strcmp (command->command, "thread-select") != 0
> +		  && thread_count () != 0)
> +		{

> +		  struct thread_info *ti = find_thread_pid (inferior_ptid);
> +		  gdb_assert (ti);	      

 These two lines can be replaced by 'struct thread_info *t = inferior_thread ()'.

> +		  target_terminal_ours ();
> +		  fprintf_unfiltered (mi->event_channel, 
> +				      "thread-selected,id=\"%d\"",
> +				      ti->num);
> +		  gdb_flush (mi->event_channel);
> +		}
> +	    }
> +	}
> +
>        mi_parse_free (command);
>      }
>  
> diff --git a/gdb/testsuite/gdb.mi/mi-pthreads.exp b/gdb/testsuite/gdb.mi/mi-pthreads.exp
> index dbb3ece..0ab5715 100644
> --- a/gdb/testsuite/gdb.mi/mi-pthreads.exp
> +++ b/gdb/testsuite/gdb.mi/mi-pthreads.exp
> @@ -55,6 +55,12 @@ proc check_mi_thread_command_set {} {
>        "\\^done,new-thread-id=\"$thread\",frame={.*}(,line=\"(-)?\[0-9\]+\",file=\".*\")?" \
>        "check_mi_thread_command_set: -thread-select $thread"
>    }
> +
> +  foreach thread $thread_list {
> +      mi_gdb_test "-interpreter-exec console \"thread $thread\"" \
> +          ".*\\^done\r\n=thread-selected,id=\"$thread\"" \
> +          "check =thread-selected: thread $thread"
> +  }
>  }
>  
>  #
> diff --git a/gdb/testsuite/lib/mi-support.exp b/gdb/testsuite/lib/mi-support.exp
> index 9ef9df9..f29ecd4 100644
> --- a/gdb/testsuite/lib/mi-support.exp
> +++ b/gdb/testsuite/lib/mi-support.exp
> @@ -816,7 +816,7 @@ proc mi_run_cmd {args} {
>  
>      send_gdb "220-exec-run $args\n"
>      gdb_expect {
> -	-re "220\\^running\r\n(\\*running,thread-id=\"\[^\"\]+\"\r\n|=thread-created,id=\"1\"\r\n)*${mi_gdb_prompt}" {
> +	-re "220\\^running\r\n(\\*running,thread-id=\"\[^\"\]+\"\r\n|=thread-created,id=\"1\"\r\n)*(=thread-selected,id=\".*\"\r\n)?${mi_gdb_prompt}" {
                                                                                                                          ^
Could you please not use .* in the mi support files?  We've recently
been through removing those for non-stop, because they're
racy --- they'll often times eat too much, and it's a good practice
to not do it from the start.

>  	}
>  	timeout {
>  	    perror "Unable to start target"
> @@ -1014,9 +1014,9 @@ proc mi_expect_stop { reason func args file line extra test } {
>  
>      set any "\[^\n\]*"
>  
> -    verbose -log "mi_expect_stop: expecting: \\*stopped,${r}${a}${bn}thread-id=\"$decimal\",stopped-threads=$any,frame=\{addr=\"$hex\",func=\"$func\",args=$args,file=\"$any$file\",fullname=\"${fullname_syntax}$file\",line=\"$line\"\}\r\n$after_stopped$prompt_re"
> +    verbose -log "mi_expect_stop: expecting: \\*stopped,${r}${a}${bn}thread-id=\"$decimal\",stopped-threads=$any,frame=\{addr=\"$hex\",func=\"$func\",args=$args,file=\"$any$file\",fullname=\"${fullname_syntax}$file\",line=\"$line\"\}\r\n$after_stopped(=thread-selected,id=\".*\"\r\n)?$prompt_re"
>      gdb_expect {
> -	-re "\\*stopped,${r}${a}${bn}thread-id=\"$decimal\",stopped-threads=$any,frame=\{addr=\"$hex\",func=\"$func\",args=$args,file=\"$any$file\",fullname=\"${fullname_syntax}$file\",line=\"($line)\"\}$after_stopped\r\n$prompt_re" {
> +	-re "\\*stopped,${r}${a}${bn}thread-id=\"$decimal\",stopped-threads=$any,frame=\{addr=\"$hex\",func=\"$func\",args=$args,file=\"$any$file\",fullname=\"${fullname_syntax}$file\",line=\"($line)\"\}$after_stopped\r\n(=thread-selected,id=\".*\"\r\n)?$prompt_re" {
>  	    pass "$test"
>              return $expect_out(2,string)
>  	}
> @@ -1433,7 +1433,7 @@ proc mi_send_resuming_command_raw {command test} {
>  
>      send_gdb "$command\n"
>      gdb_expect {
> -        -re "\\^running\r\n\\*running,thread-id=\"\[^\"\]+\"\r\n${mi_gdb_prompt}" {
> +        -re "\\^running\r\n\\*running,thread-id=\"\[^\"\]+\"\r\n(=thread-selected,id=\".*\"\r\n)?${mi_gdb_prompt}" {

                                                                                          ^ 

Same here.

>              # Note that lack of 'pass' call here -- this works around limitation
>              # in DejaGNU xfail mechanism. mi-until.exp has this:
>              #
> @@ -1491,7 +1491,7 @@ proc mi_get_stop_line {test} {
>    }
>  
>    gdb_expect {
> -      -re ".*line=\"(\[0-9\]*)\".*\r\n$prompt_re" {
> +      -re ".*line=\"(\[0-9\]*)\".*\r\n(=thread-selected,id=\".*\"\r\n)?$prompt_re" {

                                                                ^ 
Same here.

>            return $expect_out(1,string)
>        }
>        -re ".*$mi_gdb_prompt" {
-- 
Pedro Alves


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [RFC] Implement =thread-selected notification.
  2008-11-13  8:54 ` Pedro Alves
  2008-11-13 11:26   ` Pedro Alves
@ 2008-11-13 15:53   ` Vladimir Prus
  2008-11-13 16:22     ` Pedro Alves
  2008-11-13 19:19     ` Daniel Jacobowitz
  1 sibling, 2 replies; 7+ messages in thread
From: Vladimir Prus @ 2008-11-13 15:53 UTC (permalink / raw)
  To: Pedro Alves, gdb-patches

[-- Attachment #1: Type: text/plain, Size: 966 bytes --]

On Thursday 13 November 2008 00:22:54 Pedro Alves wrote:

> > +      /* The notifications are only output when the top-level
> > +	 interpreter (specified on the command line) is MI.  */      
> > +      top_name = top_level_interpreter_name ();
> > +      if (had_execution && target_has_execution 
> 
> > +	  && strstr (top_name, "mi") == top_name)
> 
> Why not,
> 
>  ui_out_is_mi_like_p (interp_ui_out (top_level_interpreter ())))
> 
> instead of relying on the interpreter name?
> 
> > +	{
> > +	  struct mi_interp *mi = top_level_interpreter_data ();
> > +	  if (!ptid_equal (previous_ptid, null_ptid)
> > +	      && !ptid_equal (inferior_ptid, previous_ptid))
> > +	    {
> 
> Checking for target_has_execution means that these new
> notifications will not be emitted when using the "thread" command while debugging
> a multi-threaded core file.

Seems like this condition is a little bit more messed up than that. I attach a reworked
patch.

Thanks,
Volodya

[-- Attachment #2: 0001-Implement-thread-selected-notification.patch --]
[-- Type: text/x-diff, Size: 9905 bytes --]

From 60404f585b782623df370cee31c07b171bb89fc9 Mon Sep 17 00:00:00 2001
From: Vladimir Prus <vladimir@codesourcery.com>
Date: Wed, 13 Aug 2008 16:32:32 +0400
Subject: [RFA] Implement =thread-selected notification.
To: gdb-patches@sources.redhat.com
X-KMail-Transport: CodeSourcery
X-KMail-Identity: 901867920

	[doc/ChangeLog]
	* gdb.texinfo (GDB/MI Async Records): Document
	=thread-selected.

	[ChangeLog]
	* mi/mi-common.h (struct mi_interp): New, moved from ...
	* mi/mi-interp.c: ...here.
	* mi/mi-main.c (mi_execute_command): If the thread changed
	as result of command, report that.

	[testsuite/ChangeLog]
	* gdb.mi/mi-pthreads.exp (check_mi_thread_command_set): Make sure
	"thread N" results in =thread-selected.
	* lib/mi-support (mi_run_cmd, mi_expect_stop)
	(mi_send_resuming_command_raw, mi_get_stop_line): Be prepared for
	=thread-selected.
---
 gdb/doc/gdb.texinfo                  |   13 ++++++++++++
 gdb/mi/mi-common.h                   |   15 +++++++++++++
 gdb/mi/mi-interp.c                   |   16 +-------------
 gdb/mi/mi-main.c                     |   37 ++++++++++++++++++++++++++++++++++
 gdb/testsuite/gdb.mi/mi-pthreads.exp |    6 +++++
 gdb/testsuite/lib/mi-support.exp     |   16 ++++++++++----
 6 files changed, 83 insertions(+), 20 deletions(-)

diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 261d1c7..ca8759d 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -19273,6 +19273,19 @@ A signal was received by the inferior.
 @itemx =thread-exited,id="@var{id}"
 A thread either was created, or has exited.  The @var{id} field
 contains the @value{GDBN} identifier of the thread.
+
+@item =thread-selected,id="@var{id}"
+Informs that the selected thread was changed as result of the last
+command.  This notification is not emitted as result of @code{-thread-select}
+command but is emitted whenever an MI command that is not documented
+to change the selected thread actually changes it.  In particular,
+invoking, directly or indirectly (via user-defined command), the CLI
+@code{thread} command, will generate this notification.
+
+We suggest that in response to this notification, front ends
+highlight the selected thread and cause subsequent commands apply to
+that thread.
+
 @end table
 
 
diff --git a/gdb/mi/mi-common.h b/gdb/mi/mi-common.h
index e47afd1..8778e74 100644
--- a/gdb/mi/mi-common.h
+++ b/gdb/mi/mi-common.h
@@ -41,4 +41,19 @@ enum async_reply_reason
 
 const char *async_reason_lookup (enum async_reply_reason reason);
 
+struct mi_interp
+{
+  /* MI's output channels */
+  struct ui_file *out;
+  struct ui_file *err;
+  struct ui_file *log;
+  struct ui_file *targ;
+  struct ui_file *event_channel;
+
+  /* This is the interpreter for the mi... */
+  struct interp *mi2_interp;
+  struct interp *mi1_interp;
+  struct interp *mi_interp;
+};
+
 #endif
diff --git a/gdb/mi/mi-interp.c b/gdb/mi/mi-interp.c
index e05b1ad..5aa0e6c 100644
--- a/gdb/mi/mi-interp.c
+++ b/gdb/mi/mi-interp.c
@@ -31,24 +31,10 @@
 #include "mi-cmds.h"
 #include "mi-out.h"
 #include "mi-console.h"
+#include "mi-common.h"
 #include "observer.h"
 #include "gdbthread.h"
 
-struct mi_interp
-{
-  /* MI's output channels */
-  struct ui_file *out;
-  struct ui_file *err;
-  struct ui_file *log;
-  struct ui_file *targ;
-  struct ui_file *event_channel;
-
-  /* This is the interpreter for the mi... */
-  struct interp *mi2_interp;
-  struct interp *mi1_interp;
-  struct interp *mi_interp;
-};
-
 /* These are the interpreter setup, etc. functions for the MI interpreter */
 static void mi_execute_command_wrapper (char *cmd);
 static void mi_command_loop (int mi_version);
diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c
index bd149ef..bd5ce69 100644
--- a/gdb/mi/mi-main.c
+++ b/gdb/mi/mi-main.c
@@ -44,6 +44,7 @@
 #include "gdb.h"
 #include "frame.h"
 #include "mi-main.h"
+#include "mi-common.h"
 #include "language.h"
 #include "valprint.h"
 #include "inferior.h"
@@ -1167,6 +1168,7 @@ mi_execute_command (char *cmd, int from_tty)
   if (command != NULL)
     {
       struct gdb_exception result;
+      ptid_t previous_ptid = inferior_ptid;
 
       if (do_timings)
 	{
@@ -1191,6 +1193,41 @@ mi_execute_command (char *cmd, int from_tty)
 	  mi_out_rewind (uiout);
 	}
 
+      if (/* The notifications are only output when the top-level
+	     interpreter (specified on the command line) is MI.  */      
+	  ui_out_is_mi_like_p (interp_ui_out (top_level_interpreter ()))
+	  /* Don't try report anything if there are no thread -- 
+	     the program is dead.  */
+	  && thread_count () != 0
+	  /* -thread-select explicitly changes thread. If frontend uses that
+	     internally, we don't want to emit =thread-selected, since
+	     =thread-selected is supposed to indicate user's intentions.  */
+	  && strcmp (command->command, "thread-select") != 0)
+	{
+	  struct mi_interp *mi = top_level_interpreter_data ();
+	  struct thread_info *ti = inferior_thread ();
+	  int report_change;
+
+	  if (command->thread == -1)
+	    {
+	      report_change = !ptid_equal (previous_ptid, null_ptid)
+		&& !ptid_equal (inferior_ptid, previous_ptid);
+	    }
+	  else
+	    {
+	      report_change = (ti->num != command->thread);
+	    }
+
+	  if (report_change)
+	    {     
+	      target_terminal_ours ();
+	      fprintf_unfiltered (mi->event_channel, 
+				  "thread-selected,id=\"%d\"",
+				  ti->num);
+	      gdb_flush (mi->event_channel);
+	    }
+	}
+
       mi_parse_free (command);
     }
 
diff --git a/gdb/testsuite/gdb.mi/mi-pthreads.exp b/gdb/testsuite/gdb.mi/mi-pthreads.exp
index dbb3ece..0ab5715 100644
--- a/gdb/testsuite/gdb.mi/mi-pthreads.exp
+++ b/gdb/testsuite/gdb.mi/mi-pthreads.exp
@@ -55,6 +55,12 @@ proc check_mi_thread_command_set {} {
       "\\^done,new-thread-id=\"$thread\",frame={.*}(,line=\"(-)?\[0-9\]+\",file=\".*\")?" \
       "check_mi_thread_command_set: -thread-select $thread"
   }
+
+  foreach thread $thread_list {
+      mi_gdb_test "-interpreter-exec console \"thread $thread\"" \
+          ".*\\^done\r\n=thread-selected,id=\"$thread\"" \
+          "check =thread-selected: thread $thread"
+  }
 }
 
 #
diff --git a/gdb/testsuite/lib/mi-support.exp b/gdb/testsuite/lib/mi-support.exp
index 9ef9df9..55116d6 100644
--- a/gdb/testsuite/lib/mi-support.exp
+++ b/gdb/testsuite/lib/mi-support.exp
@@ -30,6 +30,8 @@ global mi_inferior_tty_name
 
 set MIFLAGS "-i=mi"
 
+set thread_selected_re "=thread-selected,id=\"\[0-9+\]\"\r\n"
+
 #
 # mi_gdb_exit -- exit the GDB, killing the target program if necessary
 #
@@ -775,6 +777,7 @@ proc mi_run_cmd {args} {
 	return -1
     }
     global mi_gdb_prompt
+    global thread_selected_re
 
     if [target_info exists gdb_init_command] {
 	send_gdb "[target_info gdb_init_command]\n";
@@ -816,7 +819,7 @@ proc mi_run_cmd {args} {
 
     send_gdb "220-exec-run $args\n"
     gdb_expect {
-	-re "220\\^running\r\n(\\*running,thread-id=\"\[^\"\]+\"\r\n|=thread-created,id=\"1\"\r\n)*${mi_gdb_prompt}" {
+	-re "220\\^running\r\n(\\*running,thread-id=\"\[^\"\]+\"\r\n|=thread-created,id=\"1\"\r\n)*($thread_selected_re)?${mi_gdb_prompt}" {
 	}
 	timeout {
 	    perror "Unable to start target"
@@ -954,6 +957,7 @@ proc mi_expect_stop { reason func args file line extra test } {
     global decimal
     global fullname_syntax
     global async
+    global thread_selected_re
 
     set after_stopped ""
     set after_reason ""
@@ -1014,9 +1018,9 @@ proc mi_expect_stop { reason func args file line extra test } {
 
     set any "\[^\n\]*"
 
-    verbose -log "mi_expect_stop: expecting: \\*stopped,${r}${a}${bn}thread-id=\"$decimal\",stopped-threads=$any,frame=\{addr=\"$hex\",func=\"$func\",args=$args,file=\"$any$file\",fullname=\"${fullname_syntax}$file\",line=\"$line\"\}\r\n$after_stopped$prompt_re"
+    verbose -log "mi_expect_stop: expecting: \\*stopped,${r}${a}${bn}thread-id=\"$decimal\",stopped-threads=$any,frame=\{addr=\"$hex\",func=\"$func\",args=$args,file=\"$any$file\",fullname=\"${fullname_syntax}$file\",line=\"$line\"\}\r\n${after_stopped}($thread_selected_re)?$prompt_re"
     gdb_expect {
-	-re "\\*stopped,${r}${a}${bn}thread-id=\"$decimal\",stopped-threads=$any,frame=\{addr=\"$hex\",func=\"$func\",args=$args,file=\"$any$file\",fullname=\"${fullname_syntax}$file\",line=\"($line)\"\}$after_stopped\r\n$prompt_re" {
+	-re "\\*stopped,${r}${a}${bn}thread-id=\"$decimal\",stopped-threads=$any,frame=\{addr=\"$hex\",func=\"$func\",args=$args,file=\"$any$file\",fullname=\"${fullname_syntax}$file\",line=\"($line)\"\}${after_stopped}\r\n($thread_selected_re)?$prompt_re" {
 	    pass "$test"
             return $expect_out(2,string)
 	}
@@ -1430,10 +1434,11 @@ proc mi_tbreak {location} {
 proc mi_send_resuming_command_raw {command test} {
 
     global mi_gdb_prompt
+    global thread_selected_re
 
     send_gdb "$command\n"
     gdb_expect {
-        -re "\\^running\r\n\\*running,thread-id=\"\[^\"\]+\"\r\n${mi_gdb_prompt}" {
+        -re "\\^running\r\n\\*running,thread-id=\"\[^\"\]+\"\r\n($thread_selected_re)?${mi_gdb_prompt}" {
             # Note that lack of 'pass' call here -- this works around limitation
             # in DejaGNU xfail mechanism. mi-until.exp has this:
             #
@@ -1483,6 +1488,7 @@ proc mi_get_stop_line {test} {
 
   global mi_gdb_prompt
   global async
+  global thread_selected_re
 
   if {$async} {
       set prompt_re ""
@@ -1491,7 +1497,7 @@ proc mi_get_stop_line {test} {
   }
 
   gdb_expect {
-      -re ".*line=\"(\[0-9\]*)\".*\r\n$prompt_re" {
+      -re ".*line=\"(\[0-9\]*)\".*\r\n($thread_selected_re)?$prompt_re" {
           return $expect_out(1,string)
       }
       -re ".*$mi_gdb_prompt" {
-- 
1.5.3.5


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [RFC] Implement =thread-selected notification.
  2008-11-13 15:53   ` Vladimir Prus
@ 2008-11-13 16:22     ` Pedro Alves
  2008-11-13 19:19     ` Daniel Jacobowitz
  1 sibling, 0 replies; 7+ messages in thread
From: Pedro Alves @ 2008-11-13 16:22 UTC (permalink / raw)
  To: Vladimir Prus; +Cc: gdb-patches

> Seems like this condition is a little bit more messed up than that.

I can't claim I undertand 100% that new command->thread bit, that I'll
trust you on that.  :-)

> I attach a reworked patch.

Thanks, I'm happy with this.

-- 
Pedro Alves


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [RFC] Implement =thread-selected notification.
  2008-11-13 15:53   ` Vladimir Prus
  2008-11-13 16:22     ` Pedro Alves
@ 2008-11-13 19:19     ` Daniel Jacobowitz
  1 sibling, 0 replies; 7+ messages in thread
From: Daniel Jacobowitz @ 2008-11-13 19:19 UTC (permalink / raw)
  To: Vladimir Prus; +Cc: Pedro Alves, gdb-patches

On Thu, Nov 13, 2008 at 05:14:14PM +0300, Vladimir Prus wrote:
> +We suggest that in response to this notification, front ends
> +highlight the selected thread and cause subsequent commands apply to
> +that thread.

"cause subsequent commands to apply to that thread".
> +	  /* Don't try report anything if there are no thread -- 
> +	     the program is dead.  */

are no threads


-- 
Daniel Jacobowitz
CodeSourcery


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2008-11-13 14:40 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-11-12 23:20 [RFC] Implement =thread-selected notification Vladimir Prus
2008-11-13  5:08 ` Eli Zaretskii
2008-11-13  8:54 ` Pedro Alves
2008-11-13 11:26   ` Pedro Alves
2008-11-13 15:53   ` Vladimir Prus
2008-11-13 16:22     ` Pedro Alves
2008-11-13 19:19     ` Daniel Jacobowitz

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox