More descriptive prompt [was Re: Process exit in multi-process, and gdb's selected thread.]

Pedro Alves pedro@codesourcery.com
Tue Feb 24 18:41:00 GMT 2009


On Tuesday 24 February 2009 18:12:03, Doug Evans wrote:
> If there's general favorability of this I'll work on a patch.

This was something that had occured to be before as well when
I got tired of doing "info threads" while working on non-stop. 

This is what I was using at one point.  It added a PS1 style
formatting to the gdb command, so I could do

(gdb) set prompt (\\p \\T: \\S)

And have the prompt show up as:

 (1 Thread 0x7ffff7fd36e0 (LWP 12690): stopped) 

or, ...

 (1 Thread 0x7ffff7fd36e0 (LWP 12690): running) 

etc.

-- 
Pedro Alves

---
 gdb/event-top.c |   89 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 86 insertions(+), 3 deletions(-)

Index: src/gdb/event-top.c
===================================================================
--- src.orig/gdb/event-top.c	2009-01-14 13:37:57.000000000 +0000
+++ src/gdb/event-top.c	2009-02-24 18:33:39.000000000 +0000
@@ -33,6 +33,7 @@
 #include "cli/cli-script.h"     /* for reset_command_nest_depth */
 #include "main.h"
 #include "gdbthread.h"
+#include "gdb_obstack.h"
 
 /* For dont_repeat() */
 #include "gdbcmd.h"
@@ -244,6 +245,83 @@ change_line_handler (void)
     }
 }
 
+static char *
+expand_gdb_prompt (char *prompt)
+{
+  char *p;
+  int escape = 0;
+  struct obstack obstack;
+  obstack_init (&obstack);
+
+  for (p = prompt; *p ; p++)
+    {
+      if (escape)
+	{
+	  escape = 0;
+	  switch (*p)
+	    {
+	    case 'p':
+	      {
+		char *t = xstrprintf ("%d",
+				      pid_to_thread_id (inferior_ptid));
+		obstack_grow_str (&obstack, t);
+		xfree (t);
+		break;
+	      }
+	    case 'T':
+	      {
+		if (!ptid_equal (inferior_ptid, null_ptid))
+		  {
+		    char *t = target_pid_to_str (inferior_ptid);
+		    if (t)
+		      obstack_grow_str (&obstack, t);
+		  }
+		break;
+	      }
+	    case 'x':
+	      {
+		if (!ptid_equal (inferior_ptid, null_ptid))
+		  {
+		    char *t = target_extra_thread_info (inferior_thread ());
+		    if (t)
+		      obstack_grow_str (&obstack, t);
+		  }
+		break;
+	      }
+	    case 'S':
+	      {
+		if (!ptid_equal (inferior_ptid, null_ptid))
+		  {
+		    if (is_running (inferior_ptid))
+		      obstack_grow_str (&obstack, "running");
+		    else if (is_stopped (inferior_ptid))
+		      obstack_grow_str (&obstack, "stopped");
+		    else if (is_exited (inferior_ptid))
+		      obstack_grow_str (&obstack, "exited");
+		  }
+		break;
+	      }
+	    }
+	}
+      else
+	{
+	  switch (*p)
+	    {
+	    case '\\':
+	      escape = 1;
+	      break;
+	    default:
+	      obstack_1grow (&obstack, *p);
+	      break;
+	    }
+	}
+    }
+
+  obstack_1grow (&obstack, '\0');
+
+  return xstrdup (obstack_finish (&obstack));
+}
+
 /* Displays the prompt. The prompt that is displayed is the current
    top of the prompt stack, if the argument NEW_PROMPT is
    0. Otherwise, it displays whatever NEW_PROMPT is. This is used
@@ -260,6 +338,7 @@ display_gdb_prompt (char *new_prompt)
 {
   int prompt_length = 0;
   char *gdb_prompt = get_prompt ();
+  char *expanded_prompt;
 
   /* Reset the nesting depth used when trace-commands is set.  */
   reset_command_nest_depth ();
@@ -307,20 +386,24 @@ display_gdb_prompt (char *new_prompt)
       strcat (new_prompt, SUFFIX (0));
     }
 
+  expanded_prompt = expand_gdb_prompt (new_prompt);
+
   if (async_command_editing_p)
     {
       rl_callback_handler_remove ();
-      rl_callback_handler_install (new_prompt, input_handler);
+      rl_callback_handler_install (expanded_prompt, input_handler);
     }
   /* new_prompt at this point can be the top of the stack or the one passed in */
-  else if (new_prompt)
+  else
     {
       /* Don't use a _filtered function here.  It causes the assumed
          character position to be off, since the newline we read from
          the user is not accounted for.  */
-      fputs_unfiltered (new_prompt, gdb_stdout);
+      fputs_unfiltered (expanded_prompt, gdb_stdout);
       gdb_flush (gdb_stdout);
     }
+
+  xfree (expanded_prompt);
 }
 
 /* Used when the user requests a different annotation level, with



More information about the Gdb mailing list