This is the mail archive of the gdb-patches@sourceware.cygnus.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

RFA: thread.c: handle "q" during "info threads"


When debugging program with many threads, the "info threads" command may
generate multiple screenfuls of information interleaved with "---Type
<return> to continue, or q <return> to quit---" prompts.

If "q" is typed in response to that prompt, one of two bad things happen:

  1. If the prompt occurred between two wrapped lines describing the same
     thread, GDB ignores the quit request.

  2. Otherwise, GDB decides that the last thread displayed is the current
     thread.

Here are two patches to fix that problem.  The first patch uses the new
catch_errors() interface I proposed in my earlier post entitled "RFA:
top.c: new catch_errors + cleanup interface".  The second patch uses the
current interface.

There are no regressions for either patch on sparc-sun-solaris2.6.

Okay to commit one or the other?

Nick

[first patch follows]

Index: thread.c
===================================================================
RCS file: /cvs/src/src/gdb/thread.c,v
retrieving revision 1.1.1.11
diff -u -r1.1.1.11 thread.c
--- thread.c	2000/02/03 04:14:36	1.1.1.11
+++ thread.c	2000/04/12 11:54:51
@@ -442,6 +442,8 @@
   prune_threads ();
   target_find_new_threads ();
   current_pid = inferior_pid;
+
+  CATCH_BEGIN (NULL, RETURN_MASK_ERROR);
   for (tp = thread_list; tp; tp = tp->next)
     {
       if (tp->pid == current_pid)
@@ -462,11 +464,12 @@
 
       switch_to_thread (tp->pid);
       if (selected_frame)
-	print_only_stack_frame (selected_frame, -1, 0);
+	print_frame_info (selected_frame, -1, 0, 1);
       else
 	printf_filtered ("[No stack.]\n");
     }
 
+  CATCH_CLEANUP;
   switch_to_thread (current_pid);
 
   /* Code below copied from "up_silently_base" in "stack.c".
@@ -487,6 +490,7 @@
     {
       select_frame (cur_frame, saved_frame_level);
     }
+  CATCH_END;
 
   /* re-show current frame. */
   show_stack_frame (cur_frame);

[second patch follows]

Index: thread.c
===================================================================
RCS file: /cvs/src/src/gdb/thread.c,v
retrieving revision 1.1.1.11
diff -u -r1.1.1.11 thread.c
--- thread.c	2000/02/03 04:14:36	1.1.1.11
+++ thread.c	2000/04/12 19:57:01
@@ -43,6 +43,13 @@
 
 /* Definition of struct thread_info exported to gdbthread.h */
 
+/* Context saved by info_threads_command(). */
+
+struct info_threads_save {
+  int inferior_pid;
+  int selected_frame_level;
+};
+
 /* Prototypes for exported functions. */
 
 void _initialize_thread PARAMS ((void));
@@ -415,6 +422,37 @@
     }
 }
 
+/* Restore context saved by info_threads_command(). */
+
+static void
+info_threads_restore (void *savev)
+{
+  int counter;
+  struct frame_info *cur_frame;
+  struct info_threads_save *save = (struct info_threads_save *)savev;
+
+  switch_to_thread (save->inferior_pid);
+
+  /* Code below copied from "up_silently_base" in "stack.c".
+   * It restores the frame set by the user before the "info threads"
+   * command.  We have finished the info-threads display by switching
+   * back to the current thread.  That switch has put us at the top
+   * of the stack (leaf frame).
+   */
+  counter = save->selected_frame_level;
+  cur_frame = find_relative_frame (selected_frame, &counter);
+  if (counter != 0)
+    {
+      /* Ooops, can't restore, tell user where we are. */
+      warning ("Couldn't restore frame in current thread, at frame 0");
+      print_stack_frame (selected_frame, -1, 0);
+    }
+  else
+    {
+      select_frame (cur_frame, selected_frame_level);
+    }
+}
+
 /* Print information about currently known threads 
 
  * Note: this has the drawback that it _really_ switches
@@ -428,11 +466,9 @@
      int from_tty;
 {
   struct thread_info *tp;
-  int current_pid;
-  struct frame_info *cur_frame;
-  int saved_frame_level = selected_frame_level;
-  int counter;
   char *extra_info;
+  struct info_threads_save save;
+  struct cleanup *cleanup;
 
   /* Avoid coredumps which would happen if we tried to access a NULL
      selected_frame.  */
@@ -441,10 +477,14 @@
 
   prune_threads ();
   target_find_new_threads ();
-  current_pid = inferior_pid;
+
+  save.inferior_pid = inferior_pid;
+  save.selected_frame_level = selected_frame_level;
+  cleanup = make_cleanup (info_threads_restore, &save);
+
   for (tp = thread_list; tp; tp = tp->next)
     {
-      if (tp->pid == current_pid)
+      if (tp->pid == save.inferior_pid)
 	printf_filtered ("* ");
       else
 	printf_filtered ("  ");
@@ -462,34 +502,15 @@
 
       switch_to_thread (tp->pid);
       if (selected_frame)
-	print_only_stack_frame (selected_frame, -1, 0);
+	print_frame_info (selected_frame, -1, 0, 1);
       else
 	printf_filtered ("[No stack.]\n");
     }
-
-  switch_to_thread (current_pid);
 
-  /* Code below copied from "up_silently_base" in "stack.c".
-   * It restores the frame set by the user before the "info threads"
-   * command.  We have finished the info-threads display by switching
-   * back to the current thread.  That switch has put us at the top
-   * of the stack (leaf frame).
-   */
-  counter = saved_frame_level;
-  cur_frame = find_relative_frame (selected_frame, &counter);
-  if (counter != 0)
-    {
-      /* Ooops, can't restore, tell user where we are. */
-      warning ("Couldn't restore frame in current thread, at frame 0");
-      print_stack_frame (selected_frame, -1, 0);
-    }
-  else
-    {
-      select_frame (cur_frame, saved_frame_level);
-    }
+  do_cleanups (cleanup);
 
   /* re-show current frame. */
-  show_stack_frame (cur_frame);
+  show_stack_frame (selected_frame);
 }
 
 /* Switch from one thread to another. */

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]