gdb/exceptions.c - gdb

Global variables defined

Functions defined

Source code

  1. /* Exception (throw catch) mechanism, for GDB, the GNU debugger.

  2.    Copyright (C) 1986-2015 Free Software Foundation, Inc.

  3.    This file is part of GDB.

  4.    This program is free software; you can redistribute it and/or modify
  5.    it under the terms of the GNU General Public License as published by
  6.    the Free Software Foundation; either version 3 of the License, or
  7.    (at your option) any later version.

  8.    This program is distributed in the hope that it will be useful,
  9.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11.    GNU General Public License for more details.

  12.    You should have received a copy of the GNU General Public License
  13.    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

  14. #include "defs.h"
  15. #include "exceptions.h"
  16. #include "breakpoint.h"
  17. #include "target.h"
  18. #include "inferior.h"
  19. #include "annotate.h"
  20. #include "ui-out.h"
  21. #include "serial.h"
  22. #include "gdbthread.h"

  23. const struct gdb_exception exception_none = { 0, GDB_NO_ERROR, NULL };

  24. void
  25. prepare_to_throw_exception (void)
  26. {
  27.   clear_quit_flag ();
  28.   immediate_quit = 0;
  29. }

  30. static void
  31. print_flush (void)
  32. {
  33.   struct serial *gdb_stdout_serial;

  34.   if (deprecated_error_begin_hook)
  35.     deprecated_error_begin_hook ();

  36.   if (target_supports_terminal_ours ())
  37.     target_terminal_ours ();

  38.   /* We want all output to appear now, before we print the error.  We
  39.      have 3 levels of buffering we have to flush (it's possible that
  40.      some of these should be changed to flush the lower-level ones
  41.      too):  */

  42.   /* 1.  The _filtered buffer.  */
  43.   if (filtered_printing_initialized ())
  44.     wrap_here ("");

  45.   /* 2.  The stdio buffer.  */
  46.   gdb_flush (gdb_stdout);
  47.   gdb_flush (gdb_stderr);

  48.   /* 3.  The system-level buffer.  */
  49.   gdb_stdout_serial = serial_fdopen (1);
  50.   if (gdb_stdout_serial)
  51.     {
  52.       serial_drain_output (gdb_stdout_serial);
  53.       serial_un_fdopen (gdb_stdout_serial);
  54.     }

  55.   annotate_error_begin ();
  56. }

  57. static void
  58. print_exception (struct ui_file *file, struct gdb_exception e)
  59. {
  60.   /* KLUGE: cagney/2005-01-13: Write the string out one line at a time
  61.      as that way the MI's behavior is preserved.  */
  62.   const char *start;
  63.   const char *end;

  64.   for (start = e.message; start != NULL; start = end)
  65.     {
  66.       end = strchr (start, '\n');
  67.       if (end == NULL)
  68.         fputs_filtered (start, file);
  69.       else
  70.         {
  71.           end++;
  72.           ui_file_write (file, start, end - start);
  73.         }
  74.     }
  75.   fprintf_filtered (file, "\n");

  76.   /* Now append the annotation.  */
  77.   switch (e.reason)
  78.     {
  79.     case RETURN_QUIT:
  80.       annotate_quit ();
  81.       break;
  82.     case RETURN_ERROR:
  83.       /* Assume that these are all errors.  */
  84.       annotate_error ();
  85.       break;
  86.     default:
  87.       internal_error (__FILE__, __LINE__, _("Bad switch."));
  88.     }
  89. }

  90. void
  91. exception_print (struct ui_file *file, struct gdb_exception e)
  92. {
  93.   if (e.reason < 0 && e.message != NULL)
  94.     {
  95.       print_flush ();
  96.       print_exception (file, e);
  97.     }
  98. }

  99. void
  100. exception_fprintf (struct ui_file *file, struct gdb_exception e,
  101.                    const char *prefix, ...)
  102. {
  103.   if (e.reason < 0 && e.message != NULL)
  104.     {
  105.       va_list args;

  106.       print_flush ();

  107.       /* Print the prefix.  */
  108.       va_start (args, prefix);
  109.       vfprintf_filtered (file, prefix, args);
  110.       va_end (args);

  111.       print_exception (file, e);
  112.     }
  113. }

  114. /* Call FUNC(UIOUT, FUNC_ARGS) but wrapped within an exception
  115.    handler.  If an exception (enum return_reason) is thrown using
  116.    throw_exception() than all cleanups installed since
  117.    catch_exceptions() was entered are invoked, the (-ve) exception
  118.    value is then returned by catch_exceptions.  If FUNC() returns
  119.    normally (with a positive or zero return value) then that value is
  120.    returned by catch_exceptions().  It is an internal_error() for
  121.    FUNC() to return a negative value.

  122.    See exceptions.h for further usage details.

  123.    Must not be called with immediate_quit in effect (bad things might
  124.    happen, say we got a signal in the middle of a memcpy to quit_return).
  125.    This is an OK restriction; with very few exceptions immediate_quit can
  126.    be replaced by judicious use of QUIT.  */

  127. /* MAYBE: cagney/1999-11-05: catch_errors() in conjunction with
  128.    error() et al. could maintain a set of flags that indicate the
  129.    current state of each of the longjmp buffers.  This would give the
  130.    longjmp code the chance to detect a longjmp botch (before it gets
  131.    to longjmperror()).  Prior to 1999-11-05 this wasn't possible as
  132.    code also randomly used a SET_TOP_LEVEL macro that directly
  133.    initialized the longjmp buffers.  */

  134. int
  135. catch_exceptions (struct ui_out *uiout,
  136.                   catch_exceptions_ftype *func,
  137.                   void *func_args,
  138.                   return_mask mask)
  139. {
  140.   return catch_exceptions_with_msg (uiout, func, func_args, NULL, mask);
  141. }

  142. int
  143. catch_exceptions_with_msg (struct ui_out *func_uiout,
  144.                              catch_exceptions_ftype *func,
  145.                              void *func_args,
  146.                            char **gdberrmsg,
  147.                              return_mask mask)
  148. {
  149.   volatile struct gdb_exception exception;
  150.   volatile int val = 0;
  151.   struct ui_out *saved_uiout;

  152.   /* Save and override the global ``struct ui_out'' builder.  */
  153.   saved_uiout = current_uiout;
  154.   current_uiout = func_uiout;

  155.   TRY_CATCH (exception, RETURN_MASK_ALL)
  156.     {
  157.       val = (*func) (current_uiout, func_args);
  158.     }

  159.   /* Restore the global builder.  */
  160.   current_uiout = saved_uiout;

  161.   if (exception.reason < 0 && (mask & RETURN_MASK (exception.reason)) == 0)
  162.     {
  163.       /* The caller didn't request that the event be caught.
  164.          Rethrow.  */
  165.       throw_exception (exception);
  166.     }

  167.   exception_print (gdb_stderr, exception);
  168.   gdb_assert (val >= 0);
  169.   gdb_assert (exception.reason <= 0);
  170.   if (exception.reason < 0)
  171.     {
  172.       /* If caller wants a copy of the low-level error message, make
  173.          one.  This is used in the case of a silent error whereby the
  174.          caller may optionally want to issue the message.  */
  175.       if (gdberrmsg != NULL)
  176.         {
  177.           if (exception.message != NULL)
  178.             *gdberrmsg = xstrdup (exception.message);
  179.           else
  180.             *gdberrmsg = NULL;
  181.         }
  182.       return exception.reason;
  183.     }
  184.   return val;
  185. }

  186. /* This function is superseded by catch_exceptions().  */

  187. int
  188. catch_errors (catch_errors_ftype *func, void *func_args, char *errstring,
  189.               return_mask mask)
  190. {
  191.   volatile int val = 0;
  192.   volatile struct gdb_exception exception;
  193.   struct ui_out *saved_uiout;

  194.   /* Save the global ``struct ui_out'' builder.  */
  195.   saved_uiout = current_uiout;

  196.   TRY_CATCH (exception, RETURN_MASK_ALL)
  197.     {
  198.       val = func (func_args);
  199.     }

  200.   /* Restore the global builder.  */
  201.   current_uiout = saved_uiout;

  202.   if (exception.reason < 0 && (mask & RETURN_MASK (exception.reason)) == 0)
  203.     {
  204.       /* The caller didn't request that the event be caught.
  205.          Rethrow.  */
  206.       throw_exception (exception);
  207.     }

  208.   exception_fprintf (gdb_stderr, exception, "%s", errstring);
  209.   if (exception.reason != 0)
  210.     return 0;
  211.   return val;
  212. }