This is the mail archive of the gdb-patches@sources.redhat.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]
Other format: [Raw text]

[commit] Have catch_exception() capture the error output


MI output is littered with:

(gdb)
PASS: gdb.mi/mi-var-cmd.exp: create lsimple->integer
-var-create int * int
&"Attempt to use a type name as an expression.\n"
&"mi_cmd_var_create: unable to create variable object\n"
^error,msg="mi_cmd_var_create: unable to create variable object"
(gdb)

(notice how the error message both appears as output and as the command's result)

This occurs because the error is printed unconditionally (ignoring error_silent). Talk about a design flaw, it should be possible to capture the error and then at the call site print it, supress it, or re-format it.

The attached modifies catch_exception (but not the others) so that the error message is captured but not printed - it's left to the caller to print et.al. the message. To preserve the existing output, and keep the test results consistent, the catch_exception call sites were also modified to print the exception.

As always tested in PPC GNU/Linux.

committed,
Andrew
2005-01-13  Andrew Cagney  <cagney@gnu.org>

	* mi/mi-main.c (mi_execute_command): Print the exception.
	* cli/cli-interp.c (safe_execute_command): Print the exception.
	* exceptions.h (exception_print): Declare.
	* exceptions.c (struct catcher): Add field print_message.
	(catcher_init): Add parameter print_message, store in the catcher
	struct.
	(print_and_throw): Only print the message when print_message.
	(catch_exceptions_with_msg, catch_errors): Pass print_message=1 to
	catcher_init.
	(catch_exception): Pass print_message=0 to catcher_init.

Index: exceptions.c
===================================================================
RCS file: /cvs/src/src/gdb/exceptions.c,v
retrieving revision 1.5
diff -p -u -r1.5 exceptions.c
--- exceptions.c	14 Jan 2005 01:20:36 -0000	1.5
+++ exceptions.c	14 Jan 2005 18:50:13 -0000
@@ -69,8 +69,13 @@ struct catcher
   enum catcher_state state;
   /* Jump buffer pointing back at the exception handler.  */
   SIGJMP_BUF buf;
-  /* Status buffer belonging to that exception handler.  */
+  /* Status buffer belonging to the exception handler.  */
   volatile struct exception *exception;
+  /* Should the error / quit message be printed?  Old code assumes
+     that this file prints the error/quit message when first reported.
+     New code instead directly handles the printing of error/quit
+     messages.  */
+  int print_message;
   /* Saved/current state.  */
   int mask;
   char *saved_error_pre_print;
@@ -88,7 +93,8 @@ static SIGJMP_BUF *
 catcher_init (struct ui_out *func_uiout,
 	      char *errstring,
 	      volatile struct exception *exception,
-	      return_mask mask)
+	      return_mask mask,
+	      int print_message)
 {
   struct catcher *new_catcher = XZALLOC (struct catcher);
 
@@ -99,6 +105,7 @@ catcher_init (struct ui_out *func_uiout,
   new_catcher->exception = exception;
 
   new_catcher->mask = mask;
+  new_catcher->print_message = print_message;
 
   /* Override error/quit messages during FUNC. */
   new_catcher->saved_error_pre_print = error_pre_print;
@@ -295,6 +302,40 @@ do_write (void *data, const char *buffer
 }
 
 
+void
+exception_print (struct ui_file *file, const char *pre_print,
+		 struct exception e)
+{
+  if (e.reason < 0 && e.message != NULL)
+    {
+      target_terminal_ours ();
+      wrap_here ("");		/* Force out any buffered output */
+      gdb_flush (file);
+      annotate_error_begin ();
+      if (pre_print)
+	fputs_filtered (pre_print, file);
+
+      /* KLUGE: cagney/2005-01-13: Write the string out one line at a
+	 time as that way the MI's behavior is preserved.  */
+      {
+	const char *start;
+	const char *end;
+	for (start = e.message; start != NULL; start = end)
+	  {
+	    end = strchr (start, '\n');
+	    if (end == NULL)
+	      fputs_filtered (start, file);
+	    else
+	      {
+		end++;
+		ui_file_write (file, start, end - start);
+	      }
+	  }					    
+      }
+      fprintf_filtered (file, "\n");
+    }
+}
+
 NORETURN static void
 print_and_throw (enum return_reason reason, enum errors error,
 		 const char *prefix, const char *fmt,
@@ -322,18 +363,23 @@ print_and_throw (enum return_reason reas
   xfree (last_message);
   last_message = ui_file_xstrdup (tmp_stream, &len);
 
-  if (deprecated_error_begin_hook)
-    deprecated_error_begin_hook ();
+  /* Print the mesage to stderr, but only if the catcher isn't going
+     to handle/print it locally.  */
+  if (current_catcher->print_message)
+    {
+      if (deprecated_error_begin_hook)
+	deprecated_error_begin_hook ();
 
-  /* Write the message plus any pre_print to gdb_stderr.  */
-  target_terminal_ours ();
-  wrap_here ("");		/* Force out any buffered output */
-  gdb_flush (gdb_stdout);
-  annotate_error_begin ();
-  if (error_pre_print)
-    fputs_filtered (error_pre_print, gdb_stderr);
-  ui_file_put (tmp_stream, do_write, gdb_stderr);
-  fprintf_filtered (gdb_stderr, "\n");
+      /* Write the message plus any pre_print to gdb_stderr.  */
+      target_terminal_ours ();
+      wrap_here ("");		/* Force out any buffered output */
+      gdb_flush (gdb_stdout);
+      annotate_error_begin ();
+      if (error_pre_print)
+	fputs_filtered (error_pre_print, gdb_stderr);
+      ui_file_put (tmp_stream, do_write, gdb_stderr);
+      fprintf_filtered (gdb_stderr, "\n");
+    }
 
   /* Throw the exception.  */
   e.reason = reason;
@@ -417,7 +463,7 @@ catch_exception (struct ui_out *uiout,
 {
   volatile struct exception exception;
   SIGJMP_BUF *catch;
-  catch = catcher_init (uiout, NULL, &exception, mask);
+  catch = catcher_init (uiout, NULL, &exception, mask, 0);
   for (SIGSETJMP ((*catch));
        catcher_state_machine (CATCH_ITER);)
     (*func) (uiout, func_args);
@@ -434,7 +480,7 @@ catch_exceptions_with_msg (struct ui_out
 {
   volatile struct exception exception;
   volatile int val = 0;
-  SIGJMP_BUF *catch = catcher_init (uiout, errstring, &exception, mask);
+  SIGJMP_BUF *catch = catcher_init (uiout, errstring, &exception, mask, 1);
   for (SIGSETJMP ((*catch)); catcher_state_machine (CATCH_ITER);)
     val = (*func) (uiout, func_args);
   gdb_assert (val >= 0);
@@ -462,7 +508,7 @@ catch_errors (catch_errors_ftype *func, 
 {
   volatile int val = 0;
   volatile struct exception exception;
-  SIGJMP_BUF *catch = catcher_init (uiout, errstring, &exception, mask);
+  SIGJMP_BUF *catch = catcher_init (uiout, errstring, &exception, mask, 1);
   /* This illustrates how it is possible to nest the mechanism and
      hence catch "break".  Of course this doesn't address the need to
      also catch "return".  */
Index: exceptions.h
===================================================================
RCS file: /cvs/src/src/gdb/exceptions.h,v
retrieving revision 1.5
diff -p -u -r1.5 exceptions.h
--- exceptions.h	14 Jan 2005 02:33:24 -0000	1.5
+++ exceptions.h	14 Jan 2005 18:50:14 -0000
@@ -65,6 +65,11 @@ struct exception
 /* A pre-defined non-exception.  */
 extern const struct exception exception_none;
 
+/* If E is an exception, print it's error message on the specified
+   stream.  */
+extern void exception_print (struct ui_file *file, const char *pre_print,
+			     struct exception e);
+
 /* Throw an exception (as described by "struct exception").  Will
    execute a LONG JUMP to the inner most containing exception handler
    established using catch_exceptions() (or similar).
@@ -121,6 +126,10 @@ extern int catch_exceptions_with_msg (st
 			     	      void *func_args,
 			     	      char *errstring, char **gdberrmsg,
 				      return_mask mask);
+
+/* This function, in addition, suppresses the printing of the captured
+   error message.  It's up to the client to print it.  */
+
 extern struct exception catch_exception (struct ui_out *uiout,
 					 catch_exception_ftype *func,
 					 void *func_args,
Index: cli/cli-interp.c
===================================================================
RCS file: /cvs/src/src/gdb/cli/cli-interp.c,v
retrieving revision 1.7
diff -p -u -r1.7 cli-interp.c
--- cli/cli-interp.c	13 Jan 2005 23:31:17 -0000	1.7
+++ cli/cli-interp.c	14 Jan 2005 18:50:14 -0000
@@ -125,11 +125,16 @@ do_captured_execute_command (struct ui_o
 static struct exception
 safe_execute_command (struct ui_out *uiout, char *command, int from_tty)
 {
+  struct exception e;
   struct captured_execute_command_args args;
   args.command = command;
   args.from_tty = from_tty;
-  return catch_exception (uiout, do_captured_execute_command, &args,
-			  RETURN_MASK_ALL);
+  e = catch_exception (uiout, do_captured_execute_command, &args,
+		       RETURN_MASK_ALL);
+  /* FIXME: cagney/2005-01-13: This shouldn't be needed.  Instead the
+     caller should print the exception.  */
+  exception_print (gdb_stderr, NULL, e);
+  return e;
 }
 
 
Index: mi/mi-main.c
===================================================================
RCS file: /cvs/src/src/gdb/mi/mi-main.c,v
retrieving revision 1.71
diff -p -u -r1.71 mi-main.c
--- mi/mi-main.c	14 Jan 2005 02:33:24 -0000	1.71
+++ mi/mi-main.c	14 Jan 2005 18:50:14 -0000
@@ -1156,6 +1156,7 @@ mi_execute_command (char *cmd, int from_
       args.command = command;
       result = catch_exception (uiout, captured_mi_execute_command, &args,
 				RETURN_MASK_ALL);
+      exception_print (gdb_stderr, NULL, result);
 
       if (args.action == EXECUTE_COMMAND_SUPRESS_PROMPT)
 	{

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