Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* [PATCH 0/5] Make gdbserver use exceptions and cleanups
@ 2014-08-18  8:47 Gary Benson
  2014-08-18  8:47 ` [PATCH 2/5] Move cleanups.[ch] to common Gary Benson
                   ` (5 more replies)
  0 siblings, 6 replies; 14+ messages in thread
From: Gary Benson @ 2014-08-18  8:47 UTC (permalink / raw)
  To: gdb-patches

Hi all,

gdbserver has the rudiments of an exception system, but it's kind of
hacky.  This series converts gdbserver to use the same exceptions and
cleanups as GDB.

This series is fairly minimal in that only the catch/cleanup code in
what was "main" has been updated to use the new system.  Other parts
of gdbserver could likely be converted to TRY_CATCH and cleanups too,
but that can be done on an as-needed basis if this patch is accepted.

A side-effect of this patch is that some error messages will change
slightly, and in cases with multiple errors the error messages will
be printed in a different order.

Built and regtested on RHEL 6.5 x86_64.

Ok to commit?

Thanks,
Gary

--
http://gbenson.net/


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

* [PATCH 3/5] Introduce common/gdb_setjmp.h
  2014-08-18  8:47 [PATCH 0/5] Make gdbserver use exceptions and cleanups Gary Benson
  2014-08-18  8:47 ` [PATCH 2/5] Move cleanups.[ch] to common Gary Benson
  2014-08-18  8:47 ` [PATCH 1/5] Move internal_{,v}warning to common/errors.[ch] Gary Benson
@ 2014-08-18  8:47 ` Gary Benson
  2014-08-20 16:54   ` Pedro Alves
  2014-08-18  8:52 ` [PATCH 4/5] Introduce common/common-exceptions.[ch] Gary Benson
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 14+ messages in thread
From: Gary Benson @ 2014-08-18  8:47 UTC (permalink / raw)
  To: gdb-patches

This commit creates a new file, common/gdb_setjmp.h, to hold some
portability macros for setjmp/longjmp et al. that are used by the
exceptions subsystem and by the demangler crash catcher.

gdb/
2014-08-18  Gary Benson  <gbenson@redhat.com>

	* common/gdb_setjmp.h: New file.
	* Makefile.in (HFILES_NO_SRCDIR): Add common/gdb_setjmp.h.
	* configure.ac: Move sigsetjmp check...
	* common/common.m4: ...here.
	* configure: Regenerate.
	* cp-support.c (SIGJMP_BUF): Undefine.
	(SIGSETJMP): Likewise.
	(SIGLONGJMP): Likewise.
	* exceptions.h (gdb_setjmp.h): Include.
	(setjmp.h): Do not include.
	(EXCEPTIONS_SIGJMP_BUF): Undefine.
	(EXCEPTIONS_SIGSETJMP): Likewise.
	(EXCEPTIONS_SIGLONGJMP): Likewise.
	Replace all uses of EXCEPTIONS_SIG* macros with SIG* macros
	from gdb_setjmp.h.
	* exceptions.c: Likewise.

gdb/gdbserver/
2014-08-18  Gary Benson  <gbenson@redhat.com>

	* config.in: Regenerate.
	* configure: Likewise.
---
 gdb/ChangeLog           |   19 +++++++++++++
 gdb/Makefile.in         |    2 +-
 gdb/common/common.m4    |   11 +++++++
 gdb/common/gdb_setjmp.h |   34 +++++++++++++++++++++++
 gdb/configure           |   68 ++++++++++++++++++++++------------------------
 gdb/configure.ac        |   11 -------
 gdb/cp-support.c        |   12 --------
 gdb/exceptions.c        |    6 ++--
 gdb/exceptions.h        |   25 ++++-------------
 gdb/gdbserver/ChangeLog |    5 +++
 gdb/gdbserver/config.in |    3 ++
 gdb/gdbserver/configure |   33 ++++++++++++++++++++++
 12 files changed, 148 insertions(+), 81 deletions(-)
 create mode 100644 gdb/common/gdb_setjmp.h

diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index 1840ce7..951a738 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -939,7 +939,7 @@ common/print-utils.h common/rsp-low.h nat/i386-dregs.h x86-linux-nat.h \
 i386-linux-nat.h common/common-defs.h common/errors.h common/common-types.h \
 common/common-debug.h target/target.h target/symbol.h common/common-regcache.h
 common/common-debug.h target/target.h target/symbol.h common/common-regcache.h \
-common/cleanups.h
+common/cleanups.h common/gdb_setjmp.h
 
 # Header files that already have srcdir in them, or which are in objdir.
 
diff --git a/gdb/common/common.m4 b/gdb/common/common.m4
index 426df79..7aabd07 100644
--- a/gdb/common/common.m4
+++ b/gdb/common/common.m4
@@ -33,4 +33,15 @@ AC_DEFUN([GDB_AC_COMMON], [
   AC_CHECK_FUNCS([fdwalk getrlimit pipe pipe2 socketpair])
 
   AC_CHECK_DECLS([strerror, strstr])
+
+  dnl Check if sigsetjmp is available.  Using AC_CHECK_FUNCS won't
+  dnl do since sigsetjmp might only be defined as a macro.
+AC_CACHE_CHECK([for sigsetjmp], gdb_cv_func_sigsetjmp,
+[AC_TRY_COMPILE([
+#include <setjmp.h>
+], [sigjmp_buf env; while (! sigsetjmp (env, 1)) siglongjmp (env, 1);],
+gdb_cv_func_sigsetjmp=yes, gdb_cv_func_sigsetjmp=no)])
+if test $gdb_cv_func_sigsetjmp = yes; then
+  AC_DEFINE(HAVE_SIGSETJMP, 1, [Define if sigsetjmp is available. ])
+fi
 ])
diff --git a/gdb/common/gdb_setjmp.h b/gdb/common/gdb_setjmp.h
new file mode 100644
index 0000000..aba50a4
--- /dev/null
+++ b/gdb/common/gdb_setjmp.h
@@ -0,0 +1,34 @@
+/* Portability wrappers for setjmp and longjmp.
+   Copyright (C) 1986-2014 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef GDB_SETJMP_H
+#define GDB_SETJMP_H
+
+#include <setjmp.h>
+
+#ifdef HAVE_SIGSETJMP
+#define SIGJMP_BUF		sigjmp_buf
+#define SIGSETJMP(buf)		sigsetjmp((buf), 1)
+#define SIGLONGJMP(buf,val)	siglongjmp((buf), (val))
+#else
+#define SIGJMP_BUF		jmp_buf
+#define SIGSETJMP(buf)		setjmp(buf)
+#define SIGLONGJMP(buf,val)	longjmp((buf), (val))
+#endif
+
+#endif /* GDB_SETJMP_H */
diff --git a/gdb/configure b/gdb/configure
index 874922d..0551f95 100755
--- a/gdb/configure
+++ b/gdb/configure
@@ -11054,6 +11054,39 @@ cat >>confdefs.h <<_ACEOF
 _ACEOF
 
 
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sigsetjmp" >&5
+$as_echo_n "checking for sigsetjmp... " >&6; }
+if test "${gdb_cv_func_sigsetjmp+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <setjmp.h>
+
+int
+main ()
+{
+sigjmp_buf env; while (! sigsetjmp (env, 1)) siglongjmp (env, 1);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  gdb_cv_func_sigsetjmp=yes
+else
+  gdb_cv_func_sigsetjmp=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gdb_cv_func_sigsetjmp" >&5
+$as_echo "$gdb_cv_func_sigsetjmp" >&6; }
+if test $gdb_cv_func_sigsetjmp = yes; then
+
+$as_echo "#define HAVE_SIGSETJMP 1" >>confdefs.h
+
+fi
+
 
 # Check the return and argument types of ptrace.  No canned test for
 # this, so roll our own.
@@ -11316,41 +11349,6 @@ if test $ac_cv_func_setpgrp_void = yes; then
 fi
 fi
 
-# Check if sigsetjmp is available.  Using AC_CHECK_FUNCS won't do
-# since sigsetjmp might only be defined as a macro.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sigsetjmp" >&5
-$as_echo_n "checking for sigsetjmp... " >&6; }
-if test "${gdb_cv_func_sigsetjmp+set}" = set; then :
-  $as_echo_n "(cached) " >&6
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-#include <setjmp.h>
-
-int
-main ()
-{
-sigjmp_buf env; while (! sigsetjmp (env, 1)) siglongjmp (env, 1);
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  gdb_cv_func_sigsetjmp=yes
-else
-  gdb_cv_func_sigsetjmp=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gdb_cv_func_sigsetjmp" >&5
-$as_echo "$gdb_cv_func_sigsetjmp" >&6; }
-if test $gdb_cv_func_sigsetjmp = yes; then
-
-$as_echo "#define HAVE_SIGSETJMP 1" >>confdefs.h
-
-fi
-
 # Assume we'll default to using the included libiberty regex.
 gdb_use_included_regex=yes
 
diff --git a/gdb/configure.ac b/gdb/configure.ac
index 61919b4..26c8ecf 100644
--- a/gdb/configure.ac
+++ b/gdb/configure.ac
@@ -1441,17 +1441,6 @@ if test $ac_cv_func_setpgrp_void = yes; then
 fi
 fi
 
-# Check if sigsetjmp is available.  Using AC_CHECK_FUNCS won't do
-# since sigsetjmp might only be defined as a macro.
-AC_CACHE_CHECK([for sigsetjmp], gdb_cv_func_sigsetjmp,
-[AC_TRY_COMPILE([
-#include <setjmp.h>
-], [sigjmp_buf env; while (! sigsetjmp (env, 1)) siglongjmp (env, 1);],
-gdb_cv_func_sigsetjmp=yes, gdb_cv_func_sigsetjmp=no)])
-if test $gdb_cv_func_sigsetjmp = yes; then
-  AC_DEFINE(HAVE_SIGSETJMP, 1, [Define if sigsetjmp is available. ])
-fi
-
 # Assume we'll default to using the included libiberty regex.
 gdb_use_included_regex=yes
 
diff --git a/gdb/cp-support.c b/gdb/cp-support.c
index 20a4a07..14aaac8 100644
--- a/gdb/cp-support.c
+++ b/gdb/cp-support.c
@@ -1488,18 +1488,6 @@ cp_lookup_rtti_type (const char *name, struct block *block)
 
 static int catch_demangler_crashes = 1;
 
-/* Wrap set/long jmp so that it's more portable.  */
-
-#if defined(HAVE_SIGSETJMP)
-#define SIGJMP_BUF		sigjmp_buf
-#define SIGSETJMP(buf)		sigsetjmp((buf), 1)
-#define SIGLONGJMP(buf,val)	siglongjmp((buf), (val))
-#else
-#define SIGJMP_BUF		jmp_buf
-#define SIGSETJMP(buf)		setjmp(buf)
-#define SIGLONGJMP(buf,val)	longjmp((buf), (val))
-#endif
-
 /* Stack context and environment for demangler crash recovery.  */
 
 static SIGJMP_BUF gdb_demangle_jmp_buf;
diff --git a/gdb/exceptions.c b/gdb/exceptions.c
index 38e966c..99a147c 100644
--- a/gdb/exceptions.c
+++ b/gdb/exceptions.c
@@ -51,7 +51,7 @@ struct catcher
 {
   enum catcher_state state;
   /* Jump buffer pointing back at the exception handler.  */
-  EXCEPTIONS_SIGJMP_BUF buf;
+  SIGJMP_BUF buf;
   /* Status buffer belonging to the exception handler.  */
   volatile struct gdb_exception *exception;
   /* Saved/current state.  */
@@ -80,7 +80,7 @@ catcher_list_size (void)
   return size;
 }
 
-EXCEPTIONS_SIGJMP_BUF *
+SIGJMP_BUF *
 exceptions_state_mc_init (volatile struct gdb_exception *exception,
 			  return_mask mask)
 {
@@ -229,7 +229,7 @@ throw_exception (struct gdb_exception exception)
      be zero, by definition in defs.h.  */
   exceptions_state_mc (CATCH_THROWING);
   *current_catcher->exception = exception;
-  EXCEPTIONS_SIGLONGJMP (current_catcher->buf, exception.reason);
+  SIGLONGJMP (current_catcher->buf, exception.reason);
 }
 
 static void
diff --git a/gdb/exceptions.h b/gdb/exceptions.h
index be74ad5..e3ff672 100644
--- a/gdb/exceptions.h
+++ b/gdb/exceptions.h
@@ -21,7 +21,7 @@
 #define EXCEPTIONS_H
 
 #include "ui-out.h"
-#include <setjmp.h>
+#include "gdb_setjmp.h"
 
 /* Reasons for calling throw_exceptions().  NOTE: all reason values
    must be less than zero.  enum value 0 is reserved for internal use
@@ -114,24 +114,11 @@ struct gdb_exception
 /* A pre-defined non-exception.  */
 extern const struct gdb_exception exception_none;
 
-/* Wrap set/long jmp so that it's more portable (internal to
-   exceptions).  */
-
-#if defined(HAVE_SIGSETJMP)
-#define EXCEPTIONS_SIGJMP_BUF		sigjmp_buf
-#define EXCEPTIONS_SIGSETJMP(buf)	sigsetjmp((buf), 1)
-#define EXCEPTIONS_SIGLONGJMP(buf,val)	siglongjmp((buf), (val))
-#else
-#define EXCEPTIONS_SIGJMP_BUF		jmp_buf
-#define EXCEPTIONS_SIGSETJMP(buf)	setjmp(buf)
-#define EXCEPTIONS_SIGLONGJMP(buf,val)	longjmp((buf), (val))
-#endif
-
 /* Functions to drive the exceptions state m/c (internal to
    exceptions).  */
-EXCEPTIONS_SIGJMP_BUF *exceptions_state_mc_init (volatile struct
-						 gdb_exception *exception,
-						 return_mask mask);
+SIGJMP_BUF *exceptions_state_mc_init (volatile struct
+				      gdb_exception *exception,
+				      return_mask mask);
 int exceptions_state_mc_action_iter (void);
 int exceptions_state_mc_action_iter_1 (void);
 
@@ -159,9 +146,9 @@ int exceptions_state_mc_action_iter_1 (void);
 
 #define TRY_CATCH(EXCEPTION,MASK) \
      { \
-       EXCEPTIONS_SIGJMP_BUF *buf = \
+       SIGJMP_BUF *buf = \
 	 exceptions_state_mc_init (&(EXCEPTION), (MASK)); \
-       EXCEPTIONS_SIGSETJMP (*buf); \
+       SIGSETJMP (*buf); \
      } \
      while (exceptions_state_mc_action_iter ()) \
        while (exceptions_state_mc_action_iter_1 ())
diff --git a/gdb/gdbserver/config.in b/gdb/gdbserver/config.in
index 216c01d..7828bf9 100644
--- a/gdb/gdbserver/config.in
+++ b/gdb/gdbserver/config.in
@@ -154,6 +154,9 @@
 /* Define to 1 if you have the <signal.h> header file. */
 #undef HAVE_SIGNAL_H
 
+/* Define if sigsetjmp is available. */
+#undef HAVE_SIGSETJMP
+
 /* Define to 1 if you have the `socketpair' function. */
 #undef HAVE_SOCKETPAIR
 
diff --git a/gdb/gdbserver/configure b/gdb/gdbserver/configure
index 9c1f9a8..9495905 100755
--- a/gdb/gdbserver/configure
+++ b/gdb/gdbserver/configure
@@ -5322,6 +5322,39 @@ cat >>confdefs.h <<_ACEOF
 _ACEOF
 
 
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sigsetjmp" >&5
+$as_echo_n "checking for sigsetjmp... " >&6; }
+if test "${gdb_cv_func_sigsetjmp+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <setjmp.h>
+
+int
+main ()
+{
+sigjmp_buf env; while (! sigsetjmp (env, 1)) siglongjmp (env, 1);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  gdb_cv_func_sigsetjmp=yes
+else
+  gdb_cv_func_sigsetjmp=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gdb_cv_func_sigsetjmp" >&5
+$as_echo "$gdb_cv_func_sigsetjmp" >&6; }
+if test $gdb_cv_func_sigsetjmp = yes; then
+
+$as_echo "#define HAVE_SIGSETJMP 1" >>confdefs.h
+
+fi
+
 
 # Check for UST
 ustlibs=""
-- 
1.7.1


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

* [PATCH 2/5] Move cleanups.[ch] to common
  2014-08-18  8:47 [PATCH 0/5] Make gdbserver use exceptions and cleanups Gary Benson
@ 2014-08-18  8:47 ` Gary Benson
  2014-08-20 16:47   ` Pedro Alves
                     ` (2 more replies)
  2014-08-18  8:47 ` [PATCH 1/5] Move internal_{,v}warning to common/errors.[ch] Gary Benson
                   ` (4 subsequent siblings)
  5 siblings, 3 replies; 14+ messages in thread
From: Gary Benson @ 2014-08-18  8:47 UTC (permalink / raw)
  To: gdb-patches

This commit moves cleanups.[ch] into gdb/common/.  The only change to
the content of the files is that cleanups.c's include list was altered
to match its new location.

gdb/
2014-08-18  Gary Benson  <gbenson@redhat.com>

	* cleanups.h: Moved to...
	* common/cleanups.h: New file.
	* cleanups.c: Moved to...
	* common/cleanups.c: New file.
	* Makefile.in (SFILES): Replace cleanups.c with common/cleanups.c.
	(HFILES_NO_SRCDIR): Replace cleanups.h with common/cleanups.h.
	(cleanups.o): New rule.

gdb/gdbserver/
2014-08-18  Gary Benson  <gbenson@redhat.com>

	* Makefile.in (SFILES): Add common/cleanups.c.
	(OBS): cleanups.o.
	(cleanups.o): New rule.
---
 gdb/ChangeLog             |   10 ++
 gdb/Makefile.in           |   10 ++-
 gdb/cleanups.c            |  296 --------------------------------------------
 gdb/cleanups.h            |   69 -----------
 gdb/common/cleanups.c     |  297 +++++++++++++++++++++++++++++++++++++++++++++
 gdb/common/cleanups.h     |   69 +++++++++++
 gdb/gdbserver/ChangeLog   |    6 +
 gdb/gdbserver/Makefile.in |    7 +-
 8 files changed, 395 insertions(+), 369 deletions(-)
 delete mode 100644 gdb/cleanups.c
 delete mode 100644 gdb/cleanups.h
 create mode 100644 gdb/common/cleanups.c
 create mode 100644 gdb/common/cleanups.h

diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index e68798d..1840ce7 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -794,7 +794,7 @@ SFILES = ada-exp.y ada-lang.c ada-typeprint.c ada-valprint.c ada-tasks.c \
 	breakpoint.c break-catch-sig.c break-catch-throw.c \
 	build-id.c buildsym.c \
 	c-exp.y c-lang.c c-typeprint.c c-valprint.c c-varobj.c \
-	charset.c cleanups.c cli-out.c coffread.c coff-pe-read.c \
+	charset.c common/cleanups.c cli-out.c coffread.c coff-pe-read.c \
 	complaints.c completer.c continuations.c corefile.c corelow.c \
 	cp-abi.c cp-support.c cp-namespace.c cp-valprint.c \
 	d-exp.y d-lang.c d-support.c d-valprint.c \
@@ -885,7 +885,7 @@ objfiles.h common/vec.h disasm.h mips-tdep.h ser-base.h \
 gdb_curses.h bfd-target.h memattr.h inferior.h ax.h dummy-frame.h \
 inflow.h fbsd-nat.h ia64-libunwind-tdep.h completer.h inf-ttrace.h \
 solib-target.h gdb_vfork.h alpha-tdep.h dwarf2expr.h \
-m2-lang.h stack.h charset.h cleanups.h addrmap.h command.h solist.h source.h \
+m2-lang.h stack.h charset.h addrmap.h command.h solist.h source.h \
 target.h target-dcache.h prologue-value.h cp-abi.h tui/tui-hooks.h tui/tui.h \
 tui/tui-file.h tui/tui-command.h tui/tui-disasm.h tui/tui-wingeneral.h \
 tui/tui-windata.h tui/tui-data.h tui/tui-win.h tui/tui-stack.h \
@@ -938,6 +938,8 @@ target/wait.h target/waitstatus.h nat/linux-nat.h nat/linux-waitpid.h \
 common/print-utils.h common/rsp-low.h nat/i386-dregs.h x86-linux-nat.h \
 i386-linux-nat.h common/common-defs.h common/errors.h common/common-types.h \
 common/common-debug.h target/target.h target/symbol.h common/common-regcache.h
+common/common-debug.h target/target.h target/symbol.h common/common-regcache.h \
+common/cleanups.h
 
 # Header files that already have srcdir in them, or which are in objdir.
 
@@ -2154,6 +2156,10 @@ common-debug.o: ${srcdir}/common/common-debug.c
 	$(COMPILE) $(srcdir)/common/common-debug.c
 	$(POSTCOMPILE)
 
+cleanups.o: ${srcdir}/common/cleanups.c
+	$(COMPILE) $(srcdir)/common/cleanups.c
+	$(POSTCOMPILE)
+
 #
 # gdb/target/ dependencies
 #
diff --git a/gdb/cleanups.c b/gdb/cleanups.c
deleted file mode 100644
index ddf8e5b..0000000
--- a/gdb/cleanups.c
+++ /dev/null
@@ -1,296 +0,0 @@
-/* Cleanup routines for GDB, the GNU debugger.
-
-   Copyright (C) 1986-2014 Free Software Foundation, Inc.
-
-   This file is part of GDB.
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 3 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
-
-#include "defs.h"
-
-/* The cleanup list records things that have to be undone
-   if an error happens (descriptors to be closed, memory to be freed, etc.)
-   Each link in the chain records a function to call and an
-   argument to give it.
-
-   Use make_cleanup to add an element to the cleanup chain.
-   Use do_cleanups to do all cleanup actions back to a given
-   point in the chain.  Use discard_cleanups to remove cleanups
-   from the chain back to a given point, not doing them.
-
-   If the argument is pointer to allocated memory, then you need
-   to additionally set the 'free_arg' member to a function that will
-   free that memory.  This function will be called both when the cleanup
-   is executed and when it's discarded.  */
-
-struct cleanup
-{
-  struct cleanup *next;
-  void (*function) (void *);
-  void (*free_arg) (void *);
-  void *arg;
-};
-
-/* Used to mark the end of a cleanup chain.
-   The value is chosen so that it:
-   - is non-NULL so that make_cleanup never returns NULL,
-   - causes a segv if dereferenced
-     [though this won't catch errors that a value of, say,
-     ((struct cleanup *) -1) will]
-   - displays as something useful when printed in gdb.
-   This is const for a bit of extra robustness.
-   It is initialized to coax gcc into putting it into .rodata.
-   All fields are initialized to survive -Wextra.  */
-static const struct cleanup sentinel_cleanup = { 0, 0, 0, 0 };
-
-/* Handy macro to use when referring to sentinel_cleanup.  */
-#define SENTINEL_CLEANUP ((struct cleanup *) &sentinel_cleanup)
-
-/* Chain of cleanup actions established with make_cleanup,
-   to be executed if an error happens.  */
-static struct cleanup *cleanup_chain = SENTINEL_CLEANUP;
-
-/* Chain of cleanup actions established with make_final_cleanup,
-   to be executed when gdb exits.  */
-static struct cleanup *final_cleanup_chain = SENTINEL_CLEANUP;
-
-/* Main worker routine to create a cleanup.
-   PMY_CHAIN is a pointer to either cleanup_chain or final_cleanup_chain.
-   FUNCTION is the function to call to perform the cleanup.
-   ARG is passed to FUNCTION when called.
-   FREE_ARG, if non-NULL, is called after the cleanup is performed.
-
-   The result is a pointer to the previous chain pointer
-   to be passed later to do_cleanups or discard_cleanups.  */
-
-static struct cleanup *
-make_my_cleanup2 (struct cleanup **pmy_chain, make_cleanup_ftype *function,
-		  void *arg,  void (*free_arg) (void *))
-{
-  struct cleanup *new
-    = (struct cleanup *) xmalloc (sizeof (struct cleanup));
-  struct cleanup *old_chain = *pmy_chain;
-
-  new->next = *pmy_chain;
-  new->function = function;
-  new->free_arg = free_arg;
-  new->arg = arg;
-  *pmy_chain = new;
-
-  gdb_assert (old_chain != NULL);
-  return old_chain;
-}
-
-/* Worker routine to create a cleanup without a destructor.
-   PMY_CHAIN is a pointer to either cleanup_chain or final_cleanup_chain.
-   FUNCTION is the function to call to perform the cleanup.
-   ARG is passed to FUNCTION when called.
-
-   The result is a pointer to the previous chain pointer
-   to be passed later to do_cleanups or discard_cleanups.  */
-
-static struct cleanup *
-make_my_cleanup (struct cleanup **pmy_chain, make_cleanup_ftype *function,
-		 void *arg)
-{
-  return make_my_cleanup2 (pmy_chain, function, arg, NULL);
-}
-
-/* Add a new cleanup to the cleanup_chain,
-   and return the previous chain pointer
-   to be passed later to do_cleanups or discard_cleanups.
-   Args are FUNCTION to clean up with, and ARG to pass to it.  */
-
-struct cleanup *
-make_cleanup (make_cleanup_ftype *function, void *arg)
-{
-  return make_my_cleanup (&cleanup_chain, function, arg);
-}
-
-/* Same as make_cleanup except also includes TDOR, a destructor to free ARG.
-   DTOR is invoked when the cleanup is performed or when it is discarded.  */
-
-struct cleanup *
-make_cleanup_dtor (make_cleanup_ftype *function, void *arg,
-		   void (*dtor) (void *))
-{
-  return make_my_cleanup2 (&cleanup_chain,
-			   function, arg, dtor);
-}
-
-/* Same as make_cleanup except the cleanup is added to final_cleanup_chain.  */
-
-struct cleanup *
-make_final_cleanup (make_cleanup_ftype *function, void *arg)
-{
-  return make_my_cleanup (&final_cleanup_chain, function, arg);
-}
-
-/* Worker routine to perform cleanups.
-   PMY_CHAIN is a pointer to either cleanup_chain or final_cleanup_chain.
-   OLD_CHAIN is the result of a "make" cleanup routine.
-   Cleanups are performed until we get back to the old end of the chain.  */
-
-static void
-do_my_cleanups (struct cleanup **pmy_chain,
-		struct cleanup *old_chain)
-{
-  struct cleanup *ptr;
-
-  while ((ptr = *pmy_chain) != old_chain)
-    {
-      *pmy_chain = ptr->next;	/* Do this first in case of recursion.  */
-      (*ptr->function) (ptr->arg);
-      if (ptr->free_arg)
-	(*ptr->free_arg) (ptr->arg);
-      xfree (ptr);
-    }
-}
-
-/* Return a value that can be passed to do_cleanups, do_final_cleanups to
-   indicate perform all cleanups.  */
-
-struct cleanup *
-all_cleanups (void)
-{
-  return SENTINEL_CLEANUP;
-}
-
-/* Discard cleanups and do the actions they describe
-   until we get back to the point OLD_CHAIN in the cleanup_chain.  */
-
-void
-do_cleanups (struct cleanup *old_chain)
-{
-  do_my_cleanups (&cleanup_chain, old_chain);
-}
-
-/* Discard cleanups and do the actions they describe
-   until we get back to the point OLD_CHAIN in the final_cleanup_chain.  */
-
-void
-do_final_cleanups (struct cleanup *old_chain)
-{
-  do_my_cleanups (&final_cleanup_chain, old_chain);
-}
-
-/* Main worker routine to discard cleanups.
-   PMY_CHAIN is a pointer to either cleanup_chain or final_cleanup_chain.
-   OLD_CHAIN is the result of a "make" cleanup routine.
-   Cleanups are discarded until we get back to the old end of the chain.  */
-
-static void
-discard_my_cleanups (struct cleanup **pmy_chain,
-		     struct cleanup *old_chain)
-{
-  struct cleanup *ptr;
-
-  while ((ptr = *pmy_chain) != old_chain)
-    {
-      *pmy_chain = ptr->next;
-      if (ptr->free_arg)
-	(*ptr->free_arg) (ptr->arg);
-      xfree (ptr);
-    }
-}
-
-/* Discard cleanups, not doing the actions they describe,
-   until we get back to the point OLD_CHAIN in the cleanup chain.  */
-
-void
-discard_cleanups (struct cleanup *old_chain)
-{
-  discard_my_cleanups (&cleanup_chain, old_chain);
-}
-
-/* Discard final cleanups, not doing the actions they describe,
-   until we get back to the point OLD_CHAIN in the final cleanup chain.  */
-
-void
-discard_final_cleanups (struct cleanup *old_chain)
-{
-  discard_my_cleanups (&final_cleanup_chain, old_chain);
-}
-
-/* Main worker routine to save cleanups.
-   PMY_CHAIN is a pointer to either cleanup_chain or final_cleanup_chain.
-   The chain is emptied and the result is a pointer to the old chain.  */
-
-static struct cleanup *
-save_my_cleanups (struct cleanup **pmy_chain)
-{
-  struct cleanup *old_chain = *pmy_chain;
-
-  *pmy_chain = SENTINEL_CLEANUP;
-  return old_chain;
-}
-
-/* Set the cleanup_chain to 0, and return the old cleanup_chain.  */
-
-struct cleanup *
-save_cleanups (void)
-{
-  return save_my_cleanups (&cleanup_chain);
-}
-
-/* Set the final_cleanup_chain to 0, and return the old
-   final_cleanup_chain.  */
-
-struct cleanup *
-save_final_cleanups (void)
-{
-  return save_my_cleanups (&final_cleanup_chain);
-}
-
-/* Main worker routine to save cleanups.
-   PMY_CHAIN is a pointer to either cleanup_chain or final_cleanup_chain.
-   The chain is restored from CHAIN.  */
-
-static void
-restore_my_cleanups (struct cleanup **pmy_chain, struct cleanup *chain)
-{
-  if (*pmy_chain != SENTINEL_CLEANUP)
-    internal_warning (__FILE__, __LINE__,
-		      _("restore_my_cleanups has found a stale cleanup"));
-
-  *pmy_chain = chain;
-}
-
-/* Restore the cleanup chain from a previously saved chain.  */
-
-void
-restore_cleanups (struct cleanup *chain)
-{
-  restore_my_cleanups (&cleanup_chain, chain);
-}
-
-/* Restore the final cleanup chain from a previously saved chain.  */
-
-void
-restore_final_cleanups (struct cleanup *chain)
-{
-  restore_my_cleanups (&final_cleanup_chain, chain);
-}
-
-/* Provide a known function that does nothing, to use as a base for
-   a possibly long chain of cleanups.  This is useful where we
-   use the cleanup chain for handling normal cleanups as well as dealing
-   with cleanups that need to be done as a result of a call to error().
-   In such cases, we may not be certain where the first cleanup is, unless
-   we have a do-nothing one to always use as the base.  */
-
-void
-null_cleanup (void *arg)
-{
-}
diff --git a/gdb/cleanups.h b/gdb/cleanups.h
deleted file mode 100644
index aad5add..0000000
--- a/gdb/cleanups.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/* Cleanups.
-   Copyright (C) 1986-2014 Free Software Foundation, Inc.
-
-   This file is part of GDB.
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 3 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
-
-#ifndef CLEANUPS_H
-#define CLEANUPS_H
-
-/* Outside of cleanups.c, this is an opaque type.  */
-struct cleanup;
-
-/* NOTE: cagney/2000-03-04: This typedef is strictly for the
-   make_cleanup function declarations below.  Do not use this typedef
-   as a cast when passing functions into the make_cleanup() code.
-   Instead either use a bounce function or add a wrapper function.
-   Calling a f(char*) function with f(void*) is non-portable.  */
-typedef void (make_cleanup_ftype) (void *);
-
-/* Function type for the dtor in make_cleanup_dtor.  */
-typedef void (make_cleanup_dtor_ftype) (void *);
-
-/* WARNING: The result of the "make cleanup" routines is not the intuitive
-   choice of being a handle on the just-created cleanup.  Instead it is an
-   opaque handle of the cleanup mechanism and represents all cleanups created
-   from that point onwards.
-   The result is guaranteed to be non-NULL though.  */
-
-extern struct cleanup *make_cleanup (make_cleanup_ftype *, void *);
-
-extern struct cleanup *make_cleanup_dtor (make_cleanup_ftype *, void *,
-					  make_cleanup_dtor_ftype *);
-
-extern struct cleanup *make_final_cleanup (make_cleanup_ftype *, void *);
-
-/* A special value to pass to do_cleanups and do_final_cleanups
-   to tell them to do all cleanups.  */
-extern struct cleanup *all_cleanups (void);
-
-extern void do_cleanups (struct cleanup *);
-extern void do_final_cleanups (struct cleanup *);
-
-extern void discard_cleanups (struct cleanup *);
-extern void discard_final_cleanups (struct cleanup *);
-
-extern struct cleanup *save_cleanups (void);
-extern struct cleanup *save_final_cleanups (void);
-
-extern void restore_cleanups (struct cleanup *);
-extern void restore_final_cleanups (struct cleanup *);
-
-/* A no-op cleanup.
-   This is useful when you want to establish a known reference point
-   to pass to do_cleanups.  */
-extern void null_cleanup (void *);
-
-#endif /* CLEANUPS_H */
diff --git a/gdb/common/cleanups.c b/gdb/common/cleanups.c
new file mode 100644
index 0000000..49b643b
--- /dev/null
+++ b/gdb/common/cleanups.c
@@ -0,0 +1,297 @@
+/* Cleanup routines for GDB, the GNU debugger.
+
+   Copyright (C) 1986-2014 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include "common-defs.h"
+#include "cleanups.h"
+
+/* The cleanup list records things that have to be undone
+   if an error happens (descriptors to be closed, memory to be freed, etc.)
+   Each link in the chain records a function to call and an
+   argument to give it.
+
+   Use make_cleanup to add an element to the cleanup chain.
+   Use do_cleanups to do all cleanup actions back to a given
+   point in the chain.  Use discard_cleanups to remove cleanups
+   from the chain back to a given point, not doing them.
+
+   If the argument is pointer to allocated memory, then you need
+   to additionally set the 'free_arg' member to a function that will
+   free that memory.  This function will be called both when the cleanup
+   is executed and when it's discarded.  */
+
+struct cleanup
+{
+  struct cleanup *next;
+  void (*function) (void *);
+  void (*free_arg) (void *);
+  void *arg;
+};
+
+/* Used to mark the end of a cleanup chain.
+   The value is chosen so that it:
+   - is non-NULL so that make_cleanup never returns NULL,
+   - causes a segv if dereferenced
+     [though this won't catch errors that a value of, say,
+     ((struct cleanup *) -1) will]
+   - displays as something useful when printed in gdb.
+   This is const for a bit of extra robustness.
+   It is initialized to coax gcc into putting it into .rodata.
+   All fields are initialized to survive -Wextra.  */
+static const struct cleanup sentinel_cleanup = { 0, 0, 0, 0 };
+
+/* Handy macro to use when referring to sentinel_cleanup.  */
+#define SENTINEL_CLEANUP ((struct cleanup *) &sentinel_cleanup)
+
+/* Chain of cleanup actions established with make_cleanup,
+   to be executed if an error happens.  */
+static struct cleanup *cleanup_chain = SENTINEL_CLEANUP;
+
+/* Chain of cleanup actions established with make_final_cleanup,
+   to be executed when gdb exits.  */
+static struct cleanup *final_cleanup_chain = SENTINEL_CLEANUP;
+
+/* Main worker routine to create a cleanup.
+   PMY_CHAIN is a pointer to either cleanup_chain or final_cleanup_chain.
+   FUNCTION is the function to call to perform the cleanup.
+   ARG is passed to FUNCTION when called.
+   FREE_ARG, if non-NULL, is called after the cleanup is performed.
+
+   The result is a pointer to the previous chain pointer
+   to be passed later to do_cleanups or discard_cleanups.  */
+
+static struct cleanup *
+make_my_cleanup2 (struct cleanup **pmy_chain, make_cleanup_ftype *function,
+		  void *arg,  void (*free_arg) (void *))
+{
+  struct cleanup *new
+    = (struct cleanup *) xmalloc (sizeof (struct cleanup));
+  struct cleanup *old_chain = *pmy_chain;
+
+  new->next = *pmy_chain;
+  new->function = function;
+  new->free_arg = free_arg;
+  new->arg = arg;
+  *pmy_chain = new;
+
+  gdb_assert (old_chain != NULL);
+  return old_chain;
+}
+
+/* Worker routine to create a cleanup without a destructor.
+   PMY_CHAIN is a pointer to either cleanup_chain or final_cleanup_chain.
+   FUNCTION is the function to call to perform the cleanup.
+   ARG is passed to FUNCTION when called.
+
+   The result is a pointer to the previous chain pointer
+   to be passed later to do_cleanups or discard_cleanups.  */
+
+static struct cleanup *
+make_my_cleanup (struct cleanup **pmy_chain, make_cleanup_ftype *function,
+		 void *arg)
+{
+  return make_my_cleanup2 (pmy_chain, function, arg, NULL);
+}
+
+/* Add a new cleanup to the cleanup_chain,
+   and return the previous chain pointer
+   to be passed later to do_cleanups or discard_cleanups.
+   Args are FUNCTION to clean up with, and ARG to pass to it.  */
+
+struct cleanup *
+make_cleanup (make_cleanup_ftype *function, void *arg)
+{
+  return make_my_cleanup (&cleanup_chain, function, arg);
+}
+
+/* Same as make_cleanup except also includes TDOR, a destructor to free ARG.
+   DTOR is invoked when the cleanup is performed or when it is discarded.  */
+
+struct cleanup *
+make_cleanup_dtor (make_cleanup_ftype *function, void *arg,
+		   void (*dtor) (void *))
+{
+  return make_my_cleanup2 (&cleanup_chain,
+			   function, arg, dtor);
+}
+
+/* Same as make_cleanup except the cleanup is added to final_cleanup_chain.  */
+
+struct cleanup *
+make_final_cleanup (make_cleanup_ftype *function, void *arg)
+{
+  return make_my_cleanup (&final_cleanup_chain, function, arg);
+}
+
+/* Worker routine to perform cleanups.
+   PMY_CHAIN is a pointer to either cleanup_chain or final_cleanup_chain.
+   OLD_CHAIN is the result of a "make" cleanup routine.
+   Cleanups are performed until we get back to the old end of the chain.  */
+
+static void
+do_my_cleanups (struct cleanup **pmy_chain,
+		struct cleanup *old_chain)
+{
+  struct cleanup *ptr;
+
+  while ((ptr = *pmy_chain) != old_chain)
+    {
+      *pmy_chain = ptr->next;	/* Do this first in case of recursion.  */
+      (*ptr->function) (ptr->arg);
+      if (ptr->free_arg)
+	(*ptr->free_arg) (ptr->arg);
+      xfree (ptr);
+    }
+}
+
+/* Return a value that can be passed to do_cleanups, do_final_cleanups to
+   indicate perform all cleanups.  */
+
+struct cleanup *
+all_cleanups (void)
+{
+  return SENTINEL_CLEANUP;
+}
+
+/* Discard cleanups and do the actions they describe
+   until we get back to the point OLD_CHAIN in the cleanup_chain.  */
+
+void
+do_cleanups (struct cleanup *old_chain)
+{
+  do_my_cleanups (&cleanup_chain, old_chain);
+}
+
+/* Discard cleanups and do the actions they describe
+   until we get back to the point OLD_CHAIN in the final_cleanup_chain.  */
+
+void
+do_final_cleanups (struct cleanup *old_chain)
+{
+  do_my_cleanups (&final_cleanup_chain, old_chain);
+}
+
+/* Main worker routine to discard cleanups.
+   PMY_CHAIN is a pointer to either cleanup_chain or final_cleanup_chain.
+   OLD_CHAIN is the result of a "make" cleanup routine.
+   Cleanups are discarded until we get back to the old end of the chain.  */
+
+static void
+discard_my_cleanups (struct cleanup **pmy_chain,
+		     struct cleanup *old_chain)
+{
+  struct cleanup *ptr;
+
+  while ((ptr = *pmy_chain) != old_chain)
+    {
+      *pmy_chain = ptr->next;
+      if (ptr->free_arg)
+	(*ptr->free_arg) (ptr->arg);
+      xfree (ptr);
+    }
+}
+
+/* Discard cleanups, not doing the actions they describe,
+   until we get back to the point OLD_CHAIN in the cleanup chain.  */
+
+void
+discard_cleanups (struct cleanup *old_chain)
+{
+  discard_my_cleanups (&cleanup_chain, old_chain);
+}
+
+/* Discard final cleanups, not doing the actions they describe,
+   until we get back to the point OLD_CHAIN in the final cleanup chain.  */
+
+void
+discard_final_cleanups (struct cleanup *old_chain)
+{
+  discard_my_cleanups (&final_cleanup_chain, old_chain);
+}
+
+/* Main worker routine to save cleanups.
+   PMY_CHAIN is a pointer to either cleanup_chain or final_cleanup_chain.
+   The chain is emptied and the result is a pointer to the old chain.  */
+
+static struct cleanup *
+save_my_cleanups (struct cleanup **pmy_chain)
+{
+  struct cleanup *old_chain = *pmy_chain;
+
+  *pmy_chain = SENTINEL_CLEANUP;
+  return old_chain;
+}
+
+/* Set the cleanup_chain to 0, and return the old cleanup_chain.  */
+
+struct cleanup *
+save_cleanups (void)
+{
+  return save_my_cleanups (&cleanup_chain);
+}
+
+/* Set the final_cleanup_chain to 0, and return the old
+   final_cleanup_chain.  */
+
+struct cleanup *
+save_final_cleanups (void)
+{
+  return save_my_cleanups (&final_cleanup_chain);
+}
+
+/* Main worker routine to save cleanups.
+   PMY_CHAIN is a pointer to either cleanup_chain or final_cleanup_chain.
+   The chain is restored from CHAIN.  */
+
+static void
+restore_my_cleanups (struct cleanup **pmy_chain, struct cleanup *chain)
+{
+  if (*pmy_chain != SENTINEL_CLEANUP)
+    internal_warning (__FILE__, __LINE__,
+		      _("restore_my_cleanups has found a stale cleanup"));
+
+  *pmy_chain = chain;
+}
+
+/* Restore the cleanup chain from a previously saved chain.  */
+
+void
+restore_cleanups (struct cleanup *chain)
+{
+  restore_my_cleanups (&cleanup_chain, chain);
+}
+
+/* Restore the final cleanup chain from a previously saved chain.  */
+
+void
+restore_final_cleanups (struct cleanup *chain)
+{
+  restore_my_cleanups (&final_cleanup_chain, chain);
+}
+
+/* Provide a known function that does nothing, to use as a base for
+   a possibly long chain of cleanups.  This is useful where we
+   use the cleanup chain for handling normal cleanups as well as dealing
+   with cleanups that need to be done as a result of a call to error().
+   In such cases, we may not be certain where the first cleanup is, unless
+   we have a do-nothing one to always use as the base.  */
+
+void
+null_cleanup (void *arg)
+{
+}
diff --git a/gdb/common/cleanups.h b/gdb/common/cleanups.h
new file mode 100644
index 0000000..aad5add
--- /dev/null
+++ b/gdb/common/cleanups.h
@@ -0,0 +1,69 @@
+/* Cleanups.
+   Copyright (C) 1986-2014 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef CLEANUPS_H
+#define CLEANUPS_H
+
+/* Outside of cleanups.c, this is an opaque type.  */
+struct cleanup;
+
+/* NOTE: cagney/2000-03-04: This typedef is strictly for the
+   make_cleanup function declarations below.  Do not use this typedef
+   as a cast when passing functions into the make_cleanup() code.
+   Instead either use a bounce function or add a wrapper function.
+   Calling a f(char*) function with f(void*) is non-portable.  */
+typedef void (make_cleanup_ftype) (void *);
+
+/* Function type for the dtor in make_cleanup_dtor.  */
+typedef void (make_cleanup_dtor_ftype) (void *);
+
+/* WARNING: The result of the "make cleanup" routines is not the intuitive
+   choice of being a handle on the just-created cleanup.  Instead it is an
+   opaque handle of the cleanup mechanism and represents all cleanups created
+   from that point onwards.
+   The result is guaranteed to be non-NULL though.  */
+
+extern struct cleanup *make_cleanup (make_cleanup_ftype *, void *);
+
+extern struct cleanup *make_cleanup_dtor (make_cleanup_ftype *, void *,
+					  make_cleanup_dtor_ftype *);
+
+extern struct cleanup *make_final_cleanup (make_cleanup_ftype *, void *);
+
+/* A special value to pass to do_cleanups and do_final_cleanups
+   to tell them to do all cleanups.  */
+extern struct cleanup *all_cleanups (void);
+
+extern void do_cleanups (struct cleanup *);
+extern void do_final_cleanups (struct cleanup *);
+
+extern void discard_cleanups (struct cleanup *);
+extern void discard_final_cleanups (struct cleanup *);
+
+extern struct cleanup *save_cleanups (void);
+extern struct cleanup *save_final_cleanups (void);
+
+extern void restore_cleanups (struct cleanup *);
+extern void restore_final_cleanups (struct cleanup *);
+
+/* A no-op cleanup.
+   This is useful when you want to establish a known reference point
+   to pass to do_cleanups.  */
+extern void null_cleanup (void *);
+
+#endif /* CLEANUPS_H */
diff --git a/gdb/gdbserver/Makefile.in b/gdb/gdbserver/Makefile.in
index 18486c6..f130082 100644
--- a/gdb/gdbserver/Makefile.in
+++ b/gdb/gdbserver/Makefile.in
@@ -170,7 +170,7 @@ SFILES=	$(srcdir)/gdbreplay.c $(srcdir)/inferiors.c $(srcdir)/dll.c \
 	$(srcdir)/common/filestuff.c $(srcdir)/target/waitstatus.c \
 	$(srcdir)/nat/mips-linux-watch.c $(srcdir)/common/print-utils.c \
 	$(srcdir)/common/rsp-low.c $(srcdir)/common/errors.c \
-	$(srcdir)/common/common-debug.c
+	$(srcdir)/common/common-debug.c $(srcdir)/common/cleanups.c
 
 DEPFILES = @GDBSERVER_DEPFILES@
 
@@ -183,7 +183,7 @@ OBS = agent.o ax.o inferiors.o regcache.o remote-utils.o server.o signals.o \
       target.o waitstatus.o utils.o debug.o version.o vec.o gdb_vecs.o \
       mem-break.o hostio.o event-loop.o tracepoint.o xml-utils.o \
       common-utils.o ptid.o buffer.o format.o filestuff.o dll.o notif.o \
-      tdesc.o print-utils.o rsp-low.o errors.o common-debug.o \
+      tdesc.o print-utils.o rsp-low.o errors.o common-debug.o cleanups.o \
       $(XML_BUILTIN) $(DEPFILES) $(LIBOBJS)
 GDBREPLAY_OBS = gdbreplay.o version.o
 GDBSERVER_LIBS = @GDBSERVER_LIBS@
@@ -544,6 +544,9 @@ errors.o: ../common/errors.c
 common-debug.o: ../common/common-debug.c
 	$(COMPILE) $<
 	$(POSTCOMPILE)
+cleanups.o: ../common/cleanups.c
+	$(COMPILE) $<
+	$(POSTCOMPILE)
 waitstatus.o: ../target/waitstatus.c
 	$(COMPILE) $<
 	$(POSTCOMPILE)
-- 
1.7.1


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

* [PATCH 1/5] Move internal_{,v}warning to common/errors.[ch]
  2014-08-18  8:47 [PATCH 0/5] Make gdbserver use exceptions and cleanups Gary Benson
  2014-08-18  8:47 ` [PATCH 2/5] Move cleanups.[ch] to common Gary Benson
@ 2014-08-18  8:47 ` Gary Benson
  2014-08-18  8:47 ` [PATCH 3/5] Introduce common/gdb_setjmp.h Gary Benson
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 14+ messages in thread
From: Gary Benson @ 2014-08-18  8:47 UTC (permalink / raw)
  To: gdb-patches

This commit moves internal_warning and internal_vwarning into
common/errors.[ch].

gdb/
2014-08-18  Gary Benson  <gbenson@redhat.com>

	* common/errors.h (internal_warning): New declaration.
	(internal_vwarning): Likewise.
	* common/errors.c (internal_warning): New function.
	* utils.h (internal_warning): Don't declare.
	(internal_vwarning): Likewise.
	* utils.c (internal_warning): Removed.

gdb/gdbserver/
2014-08-18  Gary Benson  <gbenson@redhat.com>

	* utils.c (internal_vwarning): New function.
---
 gdb/ChangeLog           |    9 +++++++++
 gdb/common/errors.c     |   12 ++++++++++++
 gdb/common/errors.h     |   15 +++++++++++++++
 gdb/gdbserver/ChangeLog |    4 ++++
 gdb/gdbserver/utils.c   |   11 +++++++++++
 gdb/utils.c             |   10 ----------
 gdb/utils.h             |    7 -------
 7 files changed, 51 insertions(+), 17 deletions(-)

diff --git a/gdb/common/errors.c b/gdb/common/errors.c
index 6da2666..089c64b 100644
--- a/gdb/common/errors.c
+++ b/gdb/common/errors.c
@@ -55,3 +55,15 @@ internal_error (const char *file, int line, const char *fmt, ...)
   internal_verror (file, line, fmt, ap);
   va_end (ap);
 }
+
+/* See common/errors.h.  */
+
+void
+internal_warning (const char *file, int line, const char *fmt, ...)
+{
+  va_list ap;
+
+  va_start (ap, fmt);
+  internal_vwarning (file, line, fmt, ap);
+  va_end (ap);
+}
diff --git a/gdb/common/errors.h b/gdb/common/errors.h
index 4e6c2b3..88d77e5 100644
--- a/gdb/common/errors.h
+++ b/gdb/common/errors.h
@@ -58,6 +58,21 @@ extern void internal_error (const char *file, int line,
 extern void internal_verror (const char *file, int line,
 			     const char *fmt, va_list args)
      ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (3, 0);
+
+/* An internal problem was detected, but the requested operation can
+   still proceed.  Internal warnings indicate programming errors as
+   opposed to more general issues beyond the application's control.
+   A warning message is constructed using a printf- or vprintf-style
+   argument list.  The function "internal_vwarning" must be provided
+   by the client.  */
+
+extern void internal_warning (const char *file, int line,
+			      const char *fmt, ...)
+     ATTRIBUTE_PRINTF (3, 4);
+
+extern void internal_vwarning (const char *file, int line,
+			       const char *fmt, va_list args)
+     ATTRIBUTE_PRINTF (3, 0);
 \f
 
 /* Like "error", but the error message is constructed by combining
diff --git a/gdb/gdbserver/utils.c b/gdb/gdbserver/utils.c
index 3aac3cd..3ec4add 100644
--- a/gdb/gdbserver/utils.c
+++ b/gdb/gdbserver/utils.c
@@ -129,6 +129,17 @@ internal_verror (const char *file, int line, const char *fmt, va_list args)
   exit (1);
 }
 
+/* Report a problem internal to GDBserver.  */
+
+void
+internal_vwarning (const char *file, int line, const char *fmt, va_list args)
+{
+  fprintf (stderr,  "\
+%s:%d: A problem internal to " TOOLNAME " has been detected.\n", file, line);
+  vfprintf (stderr, fmt, args);
+  fprintf (stderr, "\n");
+}
+
 /* Convert a CORE_ADDR into a HEX string, like %lx.
    The result is stored in a circular static buffer, NUMCELLS deep.  */
 
diff --git a/gdb/utils.c b/gdb/utils.c
index 2b64023..759ec84 100644
--- a/gdb/utils.c
+++ b/gdb/utils.c
@@ -797,16 +797,6 @@ internal_vwarning (const char *file, int line, const char *fmt, va_list ap)
   internal_vproblem (&internal_warning_problem, file, line, fmt, ap);
 }
 
-void
-internal_warning (const char *file, int line, const char *string, ...)
-{
-  va_list ap;
-
-  va_start (ap, string);
-  internal_vwarning (file, line, string, ap);
-  va_end (ap);
-}
-
 static struct internal_problem demangler_warning_problem = {
   "demangler-warning", 1, internal_problem_ask, 0, internal_problem_no
 };
diff --git a/gdb/utils.h b/gdb/utils.h
index 57a1c0f..2ec3fda 100644
--- a/gdb/utils.h
+++ b/gdb/utils.h
@@ -283,13 +283,6 @@ extern char *warning_pre_print;
 
 extern void error_stream (struct ui_file *) ATTRIBUTE_NORETURN;
 
-extern void internal_vwarning (const char *file, int line,
-			       const char *, va_list ap)
-     ATTRIBUTE_PRINTF (3, 0);
-
-extern void internal_warning (const char *file, int line,
-			      const char *, ...) ATTRIBUTE_PRINTF (3, 4);
-
 extern void demangler_vwarning (const char *file, int line,
 			       const char *, va_list ap)
      ATTRIBUTE_PRINTF (3, 0);
-- 
1.7.1


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

* [PATCH 4/5] Introduce common/common-exceptions.[ch]
  2014-08-18  8:47 [PATCH 0/5] Make gdbserver use exceptions and cleanups Gary Benson
                   ` (2 preceding siblings ...)
  2014-08-18  8:47 ` [PATCH 3/5] Introduce common/gdb_setjmp.h Gary Benson
@ 2014-08-18  8:52 ` Gary Benson
  2014-08-18  9:25 ` [PATCH 5/5] Use exceptions and cleanups in gdbserver Gary Benson
  2014-08-28 15:39 ` [PATCH 0/5] Make gdbserver use exceptions and cleanups Pedro Alves
  5 siblings, 0 replies; 14+ messages in thread
From: Gary Benson @ 2014-08-18  8:52 UTC (permalink / raw)
  To: gdb-patches

This commit moves the exception throwing and catching code
into gdb/common/.  All exception printing code remains in
gdb/exceptions.[ch].

gdb/
2014-08-18  Gary Benson  <gbenson@redhat.com>

	* common/common-exceptions.h: New file.
	* common/common-exceptions.c: Likewise.
	* Makefile.in (SFILES): Add common/common-exceptions.c.
	(HFILES_NO_SRCDIR): Add common/common-exceptions.h.
	(COMMON_OBS): Add common-exceptions.o.
	(common-exceptions.o): New rule.
	* exceptions.h (common-exceptions.h): Include.
	(gdb_setjmp.h): Do not include.
	(return_reason): Moved to common-exceptions.h.
	(enum return_reason): Likewise.
	(RETURN_MASK): Likewise.
	(typedef return_mask): Likewise.
	(enum errors): Likewise.
	(struct gdb_exception): Likewise.
	(exceptions_state_mc_init): Likewise.
	(exceptions_state_mc_action_iter): Likewise.
	(exceptions_state_mc_action_iter_1): Likewise.
	(TRY_CATCH): Likewise.
	(throw_exception): Likewise.
	(throw_verror): Likewise.
	(throw_vquit): Likewise.
	(throw_error): Likewise.
	(throw_quit): Likewise.
	* exceptions.c (enum catcher_state): Moved to common-exceptions.c.
	(enum catcher_action): Likewise.
	(struct catcher): Likewise.
	(current_catcher): Likewise.
	(catcher_list_size): Likewise.
	(exceptions_state_mc_init): Likewise.
	(catcher_pop): Likewise.
	(exceptions_state_mc): Likewise.
	(exceptions_state_mc_action_iter): Likewise.
	(exceptions_state_mc_action_iter_1): Likewise.
	(throw_exception): Likewise.
	(exception_messages): Likewise.
	(exception_messages_size): Likewise.
	(throw_it): Likewise.
	(throw_verror): Likewise.
	(throw_vquit): Likewise.
	(throw_error): Likewise.
	(throw_quit): Likewise.
	(prepare_to_throw_exception): New function.

gdb/gdbserver/
2014-08-18  Gary Benson  <gbenson@redhat.com>

	* Makefile.in (SFILES): Add common/common-exceptions.c.
	(OBS): Add common-exceptions.o.
	(common-exceptions.o): New rule.
	* utils.c (prepare_to_throw_exception): New function.
---
 gdb/ChangeLog                  |   45 ++++++
 gdb/Makefile.in                |   11 +-
 gdb/common/common-exceptions.c |  308 ++++++++++++++++++++++++++++++++++++++++
 gdb/common/common-exceptions.h |  185 ++++++++++++++++++++++++
 gdb/exceptions.c               |  282 +------------------------------------
 gdb/exceptions.h               |  154 +--------------------
 gdb/gdbserver/ChangeLog        |    7 +
 gdb/gdbserver/Makefile.in      |    7 +-
 gdb/gdbserver/utils.c          |    8 +
 9 files changed, 569 insertions(+), 438 deletions(-)
 create mode 100644 gdb/common/common-exceptions.c
 create mode 100644 gdb/common/common-exceptions.h

diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index 951a738..3298825 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -851,7 +851,7 @@ SFILES = ada-exp.y ada-lang.c ada-typeprint.c ada-valprint.c ada-tasks.c \
 	common/ptid.c common/buffer.c gdb-dlfcn.c common/agent.c \
 	common/format.c common/filestuff.c btrace.c record-btrace.c ctf.c \
 	target/waitstatus.c common/print-utils.c common/rsp-low.c \
-	common/errors.c common/common-debug.c
+	common/errors.c common/common-debug.c common/common-exceptions.c
 
 LINTFILES = $(SFILES) $(YYFILES) $(CONFIG_SRCS) init.c
 
@@ -939,7 +939,7 @@ common/print-utils.h common/rsp-low.h nat/i386-dregs.h x86-linux-nat.h \
 i386-linux-nat.h common/common-defs.h common/errors.h common/common-types.h \
 common/common-debug.h target/target.h target/symbol.h common/common-regcache.h
 common/common-debug.h target/target.h target/symbol.h common/common-regcache.h \
-common/cleanups.h common/gdb_setjmp.h
+common/cleanups.h common/gdb_setjmp.h common/common-exceptions.h
 
 # Header files that already have srcdir in them, or which are in objdir.
 
@@ -1038,7 +1038,8 @@ COMMON_OBS = $(DEPFILES) $(CONFIG_OBS) $(YYOBJ) \
 	gdb_vecs.o jit.o progspace.o skip.o probe.o \
 	common-utils.o buffer.o ptid.o gdb-dlfcn.o common-agent.o \
 	format.o registry.o btrace.o record-btrace.o waitstatus.o \
-	print-utils.o rsp-low.o errors.o common-debug.o debug.o
+	print-utils.o rsp-low.o errors.o common-debug.o debug.o \
+	common-exceptions.o
 
 TSOBS = inflow.o
 
@@ -2160,6 +2161,10 @@ cleanups.o: ${srcdir}/common/cleanups.c
 	$(COMPILE) $(srcdir)/common/cleanups.c
 	$(POSTCOMPILE)
 
+common-exceptions.o: ${srcdir}/common/common-exceptions.c
+	$(COMPILE) $(srcdir)/common/common-exceptions.c
+	$(POSTCOMPILE)
+
 #
 # gdb/target/ dependencies
 #
diff --git a/gdb/common/common-exceptions.c b/gdb/common/common-exceptions.c
new file mode 100644
index 0000000..c382d86
--- /dev/null
+++ b/gdb/common/common-exceptions.c
@@ -0,0 +1,308 @@
+/* Exception (throw catch) mechanism, for GDB, the GNU debugger.
+
+   Copyright (C) 1986-2014 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include "common-defs.h"
+#include "common-exceptions.h"
+#include "cleanups.h"
+
+/* Possible catcher states.  */
+enum catcher_state {
+  /* Initial state, a new catcher has just been created.  */
+  CATCHER_CREATED,
+  /* The catch code is running.  */
+  CATCHER_RUNNING,
+  CATCHER_RUNNING_1,
+  /* The catch code threw an exception.  */
+  CATCHER_ABORTING
+};
+
+/* Possible catcher actions.  */
+enum catcher_action {
+  CATCH_ITER,
+  CATCH_ITER_1,
+  CATCH_THROWING
+};
+
+struct catcher
+{
+  enum catcher_state state;
+  /* Jump buffer pointing back at the exception handler.  */
+  SIGJMP_BUF buf;
+  /* Status buffer belonging to the exception handler.  */
+  volatile struct gdb_exception *exception;
+  /* Saved/current state.  */
+  int mask;
+  struct cleanup *saved_cleanup_chain;
+  /* Back link.  */
+  struct catcher *prev;
+};
+
+/* Where to go for throw_exception().  */
+static struct catcher *current_catcher;
+
+/* Return length of current_catcher list.  */
+
+static int
+catcher_list_size (void)
+{
+  int size;
+  struct catcher *catcher;
+
+  for (size = 0, catcher = current_catcher;
+       catcher != NULL;
+       catcher = catcher->prev)
+    ++size;
+
+  return size;
+}
+
+SIGJMP_BUF *
+exceptions_state_mc_init (volatile struct gdb_exception *exception,
+			  return_mask mask)
+{
+  struct catcher *new_catcher = XCNEW (struct catcher);
+
+  /* Start with no exception, save it's address.  */
+  exception->reason = 0;
+  exception->error = GDB_NO_ERROR;
+  exception->message = NULL;
+  new_catcher->exception = exception;
+
+  new_catcher->mask = mask;
+
+  /* Prevent error/quit during FUNC from calling cleanups established
+     prior to here.  */
+  new_catcher->saved_cleanup_chain = save_cleanups ();
+
+  /* Push this new catcher on the top.  */
+  new_catcher->prev = current_catcher;
+  current_catcher = new_catcher;
+  new_catcher->state = CATCHER_CREATED;
+
+  return &new_catcher->buf;
+}
+
+static void
+catcher_pop (void)
+{
+  struct catcher *old_catcher = current_catcher;
+
+  current_catcher = old_catcher->prev;
+
+  /* Restore the cleanup chain, the error/quit messages, and the uiout
+     builder, to their original states.  */
+
+  restore_cleanups (old_catcher->saved_cleanup_chain);
+
+  xfree (old_catcher);
+}
+
+/* Catcher state machine.  Returns non-zero if the m/c should be run
+   again, zero if it should abort.  */
+
+static int
+exceptions_state_mc (enum catcher_action action)
+{
+  switch (current_catcher->state)
+    {
+    case CATCHER_CREATED:
+      switch (action)
+	{
+	case CATCH_ITER:
+	  /* Allow the code to run the catcher.  */
+	  current_catcher->state = CATCHER_RUNNING;
+	  return 1;
+	default:
+	  internal_error (__FILE__, __LINE__, _("bad state"));
+	}
+    case CATCHER_RUNNING:
+      switch (action)
+	{
+	case CATCH_ITER:
+	  /* No error/quit has occured.  Just clean up.  */
+	  catcher_pop ();
+	  return 0;
+	case CATCH_ITER_1:
+	  current_catcher->state = CATCHER_RUNNING_1;
+	  return 1;
+	case CATCH_THROWING:
+	  current_catcher->state = CATCHER_ABORTING;
+	  /* See also throw_exception.  */
+	  return 1;
+	default:
+	  internal_error (__FILE__, __LINE__, _("bad switch"));
+	}
+    case CATCHER_RUNNING_1:
+      switch (action)
+	{
+	case CATCH_ITER:
+	  /* The did a "break" from the inner while loop.  */
+	  catcher_pop ();
+	  return 0;
+	case CATCH_ITER_1:
+	  current_catcher->state = CATCHER_RUNNING;
+	  return 0;
+	case CATCH_THROWING:
+	  current_catcher->state = CATCHER_ABORTING;
+	  /* See also throw_exception.  */
+	  return 1;
+	default:
+	  internal_error (__FILE__, __LINE__, _("bad switch"));
+	}
+    case CATCHER_ABORTING:
+      switch (action)
+	{
+	case CATCH_ITER:
+	  {
+	    struct gdb_exception exception = *current_catcher->exception;
+
+	    if (current_catcher->mask & RETURN_MASK (exception.reason))
+	      {
+		/* Exit normally if this catcher can handle this
+		   exception.  The caller analyses the func return
+		   values.  */
+		catcher_pop ();
+		return 0;
+	      }
+	    /* The caller didn't request that the event be caught,
+	       relay the event to the next containing
+	       catch_errors().  */
+	    catcher_pop ();
+	    throw_exception (exception);
+	  }
+	default:
+	  internal_error (__FILE__, __LINE__, _("bad state"));
+	}
+    default:
+      internal_error (__FILE__, __LINE__, _("bad switch"));
+    }
+}
+
+int
+exceptions_state_mc_action_iter (void)
+{
+  return exceptions_state_mc (CATCH_ITER);
+}
+
+int
+exceptions_state_mc_action_iter_1 (void)
+{
+  return exceptions_state_mc (CATCH_ITER_1);
+}
+
+/* Return EXCEPTION to the nearest containing catch_errors().  */
+
+void
+throw_exception (struct gdb_exception exception)
+{
+  prepare_to_throw_exception ();
+
+  do_cleanups (all_cleanups ());
+
+  /* Jump to the containing catch_errors() call, communicating REASON
+     to that call via setjmp's return value.  Note that REASON can't
+     be zero, by definition in defs.h.  */
+  exceptions_state_mc (CATCH_THROWING);
+  *current_catcher->exception = exception;
+  SIGLONGJMP (current_catcher->buf, exception.reason);
+}
+
+/* A stack of exception messages.
+   This is needed to handle nested calls to throw_it: we don't want to
+   xfree space for a message before it's used.
+   This can happen if we throw an exception during a cleanup:
+   An outer TRY_CATCH may have an exception message it wants to print,
+   but while doing cleanups further calls to throw_it are made.
+
+   This is indexed by the size of the current_catcher list.
+   It is a dynamically allocated array so that we don't care how deeply
+   GDB nests its TRY_CATCHs.  */
+static char **exception_messages;
+
+/* The number of currently allocated entries in exception_messages.  */
+static int exception_messages_size;
+
+static void ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (3, 0)
+throw_it (enum return_reason reason, enum errors error, const char *fmt,
+	  va_list ap)
+{
+  struct gdb_exception e;
+  char *new_message;
+  int depth = catcher_list_size ();
+
+  gdb_assert (depth > 0);
+
+  /* Note: The new message may use an old message's text.  */
+  new_message = xstrvprintf (fmt, ap);
+
+  if (depth > exception_messages_size)
+    {
+      int old_size = exception_messages_size;
+
+      exception_messages_size = depth + 10;
+      exception_messages = (char **) xrealloc (exception_messages,
+					       exception_messages_size
+					       * sizeof (char *));
+      memset (exception_messages + old_size, 0,
+	      (exception_messages_size - old_size) * sizeof (char *));
+    }
+
+  xfree (exception_messages[depth - 1]);
+  exception_messages[depth - 1] = new_message;
+
+  /* Create the exception.  */
+  e.reason = reason;
+  e.error = error;
+  e.message = new_message;
+
+  /* Throw the exception.  */
+  throw_exception (e);
+}
+
+void
+throw_verror (enum errors error, const char *fmt, va_list ap)
+{
+  throw_it (RETURN_ERROR, error, fmt, ap);
+}
+
+void
+throw_vquit (const char *fmt, va_list ap)
+{
+  throw_it (RETURN_QUIT, GDB_NO_ERROR, fmt, ap);
+}
+
+void
+throw_error (enum errors error, const char *fmt, ...)
+{
+  va_list args;
+
+  va_start (args, fmt);
+  throw_verror (error, fmt, args);
+  va_end (args);
+}
+
+void
+throw_quit (const char *fmt, ...)
+{
+  va_list args;
+
+  va_start (args, fmt);
+  throw_vquit (fmt, args);
+  va_end (args);
+}
diff --git a/gdb/common/common-exceptions.h b/gdb/common/common-exceptions.h
new file mode 100644
index 0000000..5f750c3
--- /dev/null
+++ b/gdb/common/common-exceptions.h
@@ -0,0 +1,185 @@
+/* Exception (throw catch) mechanism, for GDB, the GNU debugger.
+
+   Copyright (C) 1986-2014 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef COMMON_EXCEPTIONS_H
+#define COMMON_EXCEPTIONS_H
+
+#include "gdb_setjmp.h"
+
+/* Reasons for calling throw_exceptions().  NOTE: all reason values
+   must be less than zero.  enum value 0 is reserved for internal use
+   as the return value from an initial setjmp().  The function
+   catch_exceptions() reserves values >= 0 as legal results from its
+   wrapped function.  */
+
+enum return_reason
+  {
+    /* User interrupt.  */
+    RETURN_QUIT = -2,
+    /* Any other error.  */
+    RETURN_ERROR
+  };
+
+#define RETURN_MASK(reason)	(1 << (int)(-reason))
+
+typedef enum
+{
+  RETURN_MASK_QUIT = RETURN_MASK (RETURN_QUIT),
+  RETURN_MASK_ERROR = RETURN_MASK (RETURN_ERROR),
+  RETURN_MASK_ALL = (RETURN_MASK_QUIT | RETURN_MASK_ERROR)
+} return_mask;
+
+/* Describe all exceptions.  */
+
+enum errors {
+  GDB_NO_ERROR,
+
+  /* Any generic error, the corresponding text is in
+     exception.message.  */
+  GENERIC_ERROR,
+
+  /* Something requested was not found.  */
+  NOT_FOUND_ERROR,
+
+  /* Thread library lacks support necessary for finding thread local
+     storage.  */
+  TLS_NO_LIBRARY_SUPPORT_ERROR,
+
+  /* Load module not found while attempting to find thread local storage.  */
+  TLS_LOAD_MODULE_NOT_FOUND_ERROR,
+
+  /* Thread local storage has not been allocated yet.  */
+  TLS_NOT_ALLOCATED_YET_ERROR,
+
+  /* Something else went wrong while attempting to find thread local
+     storage.  The ``struct gdb_exception'' message field provides
+     more detail.  */
+  TLS_GENERIC_ERROR,
+
+  /* Problem parsing an XML document.  */
+  XML_PARSE_ERROR,
+
+  /* Error accessing memory.  */
+  MEMORY_ERROR,
+
+  /* Value not available.  E.g., a register was not collected in a
+     traceframe.  */
+  NOT_AVAILABLE_ERROR,
+
+  /* Value was optimized out.  Note: if the value was a register, this
+     means the register was not saved in the frame.  */
+  OPTIMIZED_OUT_ERROR,
+
+  /* DW_OP_GNU_entry_value resolving failed.  */
+  NO_ENTRY_VALUE_ERROR,
+
+  /* Target throwing an error has been closed.  Current command should be
+     aborted as the inferior state is no longer valid.  */
+  TARGET_CLOSE_ERROR,
+
+  /* An undefined command was executed.  */
+  UNDEFINED_COMMAND_ERROR,
+
+  /* Requested feature, method, mechanism, etc. is not supported.  */
+  NOT_SUPPORTED_ERROR,
+
+  /* Add more errors here.  */
+  NR_ERRORS
+};
+
+struct gdb_exception
+{
+  enum return_reason reason;
+  enum errors error;
+  const char *message;
+};
+
+/* Functions to drive the exceptions state machine.  Though declared
+   here by necessity, these functions should be considered internal to
+   the exceptions subsystem and not used other than via the TRY_CATCH
+   macro defined below.  */
+
+extern SIGJMP_BUF *exceptions_state_mc_init (volatile struct
+					     gdb_exception *exception,
+					     return_mask mask);
+extern int exceptions_state_mc_action_iter (void);
+extern int exceptions_state_mc_action_iter_1 (void);
+
+/* Macro to wrap up standard try/catch behavior.
+
+   The double loop lets us correctly handle code "break"ing out of the
+   try catch block.  (It works as the "break" only exits the inner
+   "while" loop, the outer for loop detects this handling it
+   correctly.)  Of course "return" and "goto" are not so lucky.
+
+   For instance:
+
+   *INDENT-OFF*
+
+   volatile struct gdb_exception e;
+   TRY_CATCH (e, RETURN_MASK_ERROR)
+     {
+     }
+   switch (e.reason)
+     {
+     case RETURN_ERROR: ...
+     }
+
+  */
+
+#define TRY_CATCH(EXCEPTION,MASK) \
+     { \
+       SIGJMP_BUF *buf = \
+	 exceptions_state_mc_init (&(EXCEPTION), (MASK)); \
+       SIGSETJMP (*buf); \
+     } \
+     while (exceptions_state_mc_action_iter ()) \
+       while (exceptions_state_mc_action_iter_1 ())
+
+/* *INDENT-ON* */
+
+/* Hook to allow client-specific actions to be performed prior to
+   throwing an exception.  This function must be provided by the
+   client, and will be called before any cleanups are run.  */
+
+extern void prepare_to_throw_exception (void);
+
+/* Throw an exception (as described by "struct gdb_exception").  Will
+   execute a LONG JUMP to the inner most containing exception handler
+   established using catch_exceptions() (or similar).
+
+   Code normally throws an exception using error() et.al.  For various
+   reaons, GDB also contains code that throws an exception directly.
+   For instance, the remote*.c targets contain CNTRL-C signal handlers
+   that propogate the QUIT event up the exception chain.  ``This could
+   be a good thing or a dangerous thing.'' -- the Existential
+   Wombat.  */
+
+extern void throw_exception (struct gdb_exception exception)
+     ATTRIBUTE_NORETURN;
+extern void throw_verror (enum errors, const char *fmt, va_list ap)
+     ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (2, 0);
+extern void throw_vquit (const char *fmt, va_list ap)
+     ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (1, 0);
+extern void throw_error (enum errors error, const char *fmt, ...)
+     ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (2, 3);
+extern void throw_quit (const char *fmt, ...)
+     ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (1, 2);
+
+#endif /* COMMON_EXCEPTIONS_H */
diff --git a/gdb/exceptions.c b/gdb/exceptions.c
index 99a147c..5533758 100644
--- a/gdb/exceptions.c
+++ b/gdb/exceptions.c
@@ -29,207 +29,11 @@
 
 const struct gdb_exception exception_none = { 0, GDB_NO_ERROR, NULL };
 
-/* Possible catcher states.  */
-enum catcher_state {
-  /* Initial state, a new catcher has just been created.  */
-  CATCHER_CREATED,
-  /* The catch code is running.  */
-  CATCHER_RUNNING,
-  CATCHER_RUNNING_1,
-  /* The catch code threw an exception.  */
-  CATCHER_ABORTING
-};
-
-/* Possible catcher actions.  */
-enum catcher_action {
-  CATCH_ITER,
-  CATCH_ITER_1,
-  CATCH_THROWING
-};
-
-struct catcher
-{
-  enum catcher_state state;
-  /* Jump buffer pointing back at the exception handler.  */
-  SIGJMP_BUF buf;
-  /* Status buffer belonging to the exception handler.  */
-  volatile struct gdb_exception *exception;
-  /* Saved/current state.  */
-  int mask;
-  struct cleanup *saved_cleanup_chain;
-  /* Back link.  */
-  struct catcher *prev;
-};
-
-/* Where to go for throw_exception().  */
-static struct catcher *current_catcher;
-
-/* Return length of current_catcher list.  */
-
-static int
-catcher_list_size (void)
-{
-  int size;
-  struct catcher *catcher;
-
-  for (size = 0, catcher = current_catcher;
-       catcher != NULL;
-       catcher = catcher->prev)
-    ++size;
-
-  return size;
-}
-
-SIGJMP_BUF *
-exceptions_state_mc_init (volatile struct gdb_exception *exception,
-			  return_mask mask)
-{
-  struct catcher *new_catcher = XCNEW (struct catcher);
-
-  /* Start with no exception, save it's address.  */
-  exception->reason = 0;
-  exception->error = GDB_NO_ERROR;
-  exception->message = NULL;
-  new_catcher->exception = exception;
-
-  new_catcher->mask = mask;
-
-  /* Prevent error/quit during FUNC from calling cleanups established
-     prior to here.  */
-  new_catcher->saved_cleanup_chain = save_cleanups ();
-
-  /* Push this new catcher on the top.  */
-  new_catcher->prev = current_catcher;
-  current_catcher = new_catcher;
-  new_catcher->state = CATCHER_CREATED;
-
-  return &new_catcher->buf;
-}
-
-static void
-catcher_pop (void)
-{
-  struct catcher *old_catcher = current_catcher;
-
-  current_catcher = old_catcher->prev;
-
-  /* Restore the cleanup chain, the error/quit messages, and the uiout
-     builder, to their original states.  */
-
-  restore_cleanups (old_catcher->saved_cleanup_chain);
-
-  xfree (old_catcher);
-}
-
-/* Catcher state machine.  Returns non-zero if the m/c should be run
-   again, zero if it should abort.  */
-
-static int
-exceptions_state_mc (enum catcher_action action)
-{
-  switch (current_catcher->state)
-    {
-    case CATCHER_CREATED:
-      switch (action)
-	{
-	case CATCH_ITER:
-	  /* Allow the code to run the catcher.  */
-	  current_catcher->state = CATCHER_RUNNING;
-	  return 1;
-	default:
-	  internal_error (__FILE__, __LINE__, _("bad state"));
-	}
-    case CATCHER_RUNNING:
-      switch (action)
-	{
-	case CATCH_ITER:
-	  /* No error/quit has occured.  Just clean up.  */
-	  catcher_pop ();
-	  return 0;
-	case CATCH_ITER_1:
-	  current_catcher->state = CATCHER_RUNNING_1;
-	  return 1;
-	case CATCH_THROWING:
-	  current_catcher->state = CATCHER_ABORTING;
-	  /* See also throw_exception.  */
-	  return 1;
-	default:
-	  internal_error (__FILE__, __LINE__, _("bad switch"));
-	}
-    case CATCHER_RUNNING_1:
-      switch (action)
-	{
-	case CATCH_ITER:
-	  /* The did a "break" from the inner while loop.  */
-	  catcher_pop ();
-	  return 0;
-	case CATCH_ITER_1:
-	  current_catcher->state = CATCHER_RUNNING;
-	  return 0;
-	case CATCH_THROWING:
-	  current_catcher->state = CATCHER_ABORTING;
-	  /* See also throw_exception.  */
-	  return 1;
-	default:
-	  internal_error (__FILE__, __LINE__, _("bad switch"));
-	}
-    case CATCHER_ABORTING:
-      switch (action)
-	{
-	case CATCH_ITER:
-	  {
-	    struct gdb_exception exception = *current_catcher->exception;
-
-	    if (current_catcher->mask & RETURN_MASK (exception.reason))
-	      {
-		/* Exit normally if this catcher can handle this
-		   exception.  The caller analyses the func return
-		   values.  */
-		catcher_pop ();
-		return 0;
-	      }
-	    /* The caller didn't request that the event be caught,
-	       relay the event to the next containing
-	       catch_errors().  */
-	    catcher_pop ();
-	    throw_exception (exception);
-	  }
-	default:
-	  internal_error (__FILE__, __LINE__, _("bad state"));
-	}
-    default:
-      internal_error (__FILE__, __LINE__, _("bad switch"));
-    }
-}
-
-int
-exceptions_state_mc_action_iter (void)
-{
-  return exceptions_state_mc (CATCH_ITER);
-}
-
-int
-exceptions_state_mc_action_iter_1 (void)
-{
-  return exceptions_state_mc (CATCH_ITER_1);
-}
-
-/* Return EXCEPTION to the nearest containing catch_errors().  */
-
 void
-throw_exception (struct gdb_exception exception)
+prepare_to_throw_exception (void)
 {
   clear_quit_flag ();
   immediate_quit = 0;
-
-  do_cleanups (all_cleanups ());
-
-  /* Jump to the containing catch_errors() call, communicating REASON
-     to that call via setjmp's return value.  Note that REASON can't
-     be zero, by definition in defs.h.  */
-  exceptions_state_mc (CATCH_THROWING);
-  *current_catcher->exception = exception;
-  SIGLONGJMP (current_catcher->buf, exception.reason);
 }
 
 static void
@@ -329,90 +133,6 @@ exception_fprintf (struct ui_file *file, struct gdb_exception e,
     }
 }
 
-/* A stack of exception messages.
-   This is needed to handle nested calls to throw_it: we don't want to
-   xfree space for a message before it's used.
-   This can happen if we throw an exception during a cleanup:
-   An outer TRY_CATCH may have an exception message it wants to print,
-   but while doing cleanups further calls to throw_it are made.
-
-   This is indexed by the size of the current_catcher list.
-   It is a dynamically allocated array so that we don't care how deeply
-   GDB nests its TRY_CATCHs.  */
-static char **exception_messages;
-
-/* The number of currently allocated entries in exception_messages.  */
-static int exception_messages_size;
-
-static void ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (3, 0)
-throw_it (enum return_reason reason, enum errors error, const char *fmt,
-	  va_list ap)
-{
-  struct gdb_exception e;
-  char *new_message;
-  int depth = catcher_list_size ();
-
-  gdb_assert (depth > 0);
-
-  /* Note: The new message may use an old message's text.  */
-  new_message = xstrvprintf (fmt, ap);
-
-  if (depth > exception_messages_size)
-    {
-      int old_size = exception_messages_size;
-
-      exception_messages_size = depth + 10;
-      exception_messages = (char **) xrealloc (exception_messages,
-					       exception_messages_size
-					       * sizeof (char *));
-      memset (exception_messages + old_size, 0,
-	      (exception_messages_size - old_size) * sizeof (char *));
-    }
-
-  xfree (exception_messages[depth - 1]);
-  exception_messages[depth - 1] = new_message;
-
-  /* Create the exception.  */
-  e.reason = reason;
-  e.error = error;
-  e.message = new_message;
-
-  /* Throw the exception.  */
-  throw_exception (e);
-}
-
-void
-throw_verror (enum errors error, const char *fmt, va_list ap)
-{
-  throw_it (RETURN_ERROR, error, fmt, ap);
-}
-
-void
-throw_vquit (const char *fmt, va_list ap)
-{
-  throw_it (RETURN_QUIT, GDB_NO_ERROR, fmt, ap);
-}
-
-void
-throw_error (enum errors error, const char *fmt, ...)
-{
-  va_list args;
-
-  va_start (args, fmt);
-  throw_verror (error, fmt, args);
-  va_end (args);
-}
-
-void
-throw_quit (const char *fmt, ...)
-{
-  va_list args;
-
-  va_start (args, fmt);
-  throw_vquit (fmt, args);
-  va_end (args);
-}
-
 /* Call FUNC(UIOUT, FUNC_ARGS) but wrapped within an exception
    handler.  If an exception (enum return_reason) is thrown using
    throw_exception() than all cleanups installed since
diff --git a/gdb/exceptions.h b/gdb/exceptions.h
index e3ff672..00d2b61 100644
--- a/gdb/exceptions.h
+++ b/gdb/exceptions.h
@@ -20,142 +20,12 @@
 #ifndef EXCEPTIONS_H
 #define EXCEPTIONS_H
 
+#include "common-exceptions.h"
 #include "ui-out.h"
-#include "gdb_setjmp.h"
-
-/* Reasons for calling throw_exceptions().  NOTE: all reason values
-   must be less than zero.  enum value 0 is reserved for internal use
-   as the return value from an initial setjmp().  The function
-   catch_exceptions() reserves values >= 0 as legal results from its
-   wrapped function.  */
-
-enum return_reason
-  {
-    /* User interrupt.  */
-    RETURN_QUIT = -2,
-    /* Any other error.  */
-    RETURN_ERROR
-  };
-
-#define RETURN_MASK(reason)	(1 << (int)(-reason))
-
-typedef enum
-{
-  RETURN_MASK_QUIT = RETURN_MASK (RETURN_QUIT),
-  RETURN_MASK_ERROR = RETURN_MASK (RETURN_ERROR),
-  RETURN_MASK_ALL = (RETURN_MASK_QUIT | RETURN_MASK_ERROR)
-} return_mask;
-
-/* Describe all exceptions.  */
-
-enum errors {
-  GDB_NO_ERROR,
-
-  /* Any generic error, the corresponding text is in
-     exception.message.  */
-  GENERIC_ERROR,
-
-  /* Something requested was not found.  */
-  NOT_FOUND_ERROR,
-
-  /* Thread library lacks support necessary for finding thread local
-     storage.  */
-  TLS_NO_LIBRARY_SUPPORT_ERROR,
-
-  /* Load module not found while attempting to find thread local storage.  */
-  TLS_LOAD_MODULE_NOT_FOUND_ERROR,
-
-  /* Thread local storage has not been allocated yet.  */
-  TLS_NOT_ALLOCATED_YET_ERROR,
-
-  /* Something else went wrong while attempting to find thread local
-     storage.  The ``struct gdb_exception'' message field provides
-     more detail.  */
-  TLS_GENERIC_ERROR,
-
-  /* Problem parsing an XML document.  */
-  XML_PARSE_ERROR,
-
-  /* Error accessing memory.  */
-  MEMORY_ERROR,
-
-  /* Value not available.  E.g., a register was not collected in a
-     traceframe.  */
-  NOT_AVAILABLE_ERROR,
-
-  /* Value was optimized out.  Note: if the value was a register, this
-     means the register was not saved in the frame.  */
-  OPTIMIZED_OUT_ERROR,
-
-  /* DW_OP_GNU_entry_value resolving failed.  */
-  NO_ENTRY_VALUE_ERROR,
-
-  /* Target throwing an error has been closed.  Current command should be
-     aborted as the inferior state is no longer valid.  */
-  TARGET_CLOSE_ERROR,
-
-  /* An undefined command was executed.  */
-  UNDEFINED_COMMAND_ERROR,
-
-  /* Requested feature, method, mechanism, etc. is not supported.  */
-  NOT_SUPPORTED_ERROR,
-
-  /* Add more errors here.  */
-  NR_ERRORS
-};
-
-struct gdb_exception
-{
-  enum return_reason reason;
-  enum errors error;
-  const char *message;
-};
 
 /* A pre-defined non-exception.  */
 extern const struct gdb_exception exception_none;
 
-/* Functions to drive the exceptions state m/c (internal to
-   exceptions).  */
-SIGJMP_BUF *exceptions_state_mc_init (volatile struct
-				      gdb_exception *exception,
-				      return_mask mask);
-int exceptions_state_mc_action_iter (void);
-int exceptions_state_mc_action_iter_1 (void);
-
-/* Macro to wrap up standard try/catch behavior.
-
-   The double loop lets us correctly handle code "break"ing out of the
-   try catch block.  (It works as the "break" only exits the inner
-   "while" loop, the outer for loop detects this handling it
-   correctly.)  Of course "return" and "goto" are not so lucky.
-
-   For instance:
-
-   *INDENT-OFF*
-
-   volatile struct gdb_exception e;
-   TRY_CATCH (e, RETURN_MASK_ERROR)
-     {
-     }
-   switch (e.reason)
-     {
-     case RETURN_ERROR: ...
-     }
-
-  */
-
-#define TRY_CATCH(EXCEPTION,MASK) \
-     { \
-       SIGJMP_BUF *buf = \
-	 exceptions_state_mc_init (&(EXCEPTION), (MASK)); \
-       SIGSETJMP (*buf); \
-     } \
-     while (exceptions_state_mc_action_iter ()) \
-       while (exceptions_state_mc_action_iter_1 ())
-
-/* *INDENT-ON* */
-
-
 /* If E is an exception, print it's error message on the specified
    stream.  For _fprintf, prefix the message with PREFIX...  */
 extern void exception_print (struct ui_file *file, struct gdb_exception e);
@@ -163,28 +33,6 @@ extern void exception_fprintf (struct ui_file *file, struct gdb_exception e,
 			       const char *prefix,
 			       ...) ATTRIBUTE_PRINTF (3, 4);
 
-/* Throw an exception (as described by "struct gdb_exception").  Will
-   execute a LONG JUMP to the inner most containing exception handler
-   established using catch_exceptions() (or similar).
-
-   Code normally throws an exception using error() et.al.  For various
-   reaons, GDB also contains code that throws an exception directly.
-   For instance, the remote*.c targets contain CNTRL-C signal handlers
-   that propogate the QUIT event up the exception chain.  ``This could
-   be a good thing or a dangerous thing.'' -- the Existential
-   Wombat.  */
-
-extern void throw_exception (struct gdb_exception exception)
-     ATTRIBUTE_NORETURN;
-extern void throw_verror (enum errors, const char *fmt, va_list ap)
-     ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (2, 0);
-extern void throw_vquit (const char *fmt, va_list ap)
-     ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (1, 0);
-extern void throw_error (enum errors error, const char *fmt, ...)
-     ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (2, 3);
-extern void throw_quit (const char *fmt, ...)
-     ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (1, 2);
-
 /* Call FUNC(UIOUT, FUNC_ARGS) but wrapped within an exception
    handler.  If an exception (enum return_reason) is thrown using
    throw_exception() than all cleanups installed since
diff --git a/gdb/gdbserver/Makefile.in b/gdb/gdbserver/Makefile.in
index f130082..21ac6f2 100644
--- a/gdb/gdbserver/Makefile.in
+++ b/gdb/gdbserver/Makefile.in
@@ -170,7 +170,8 @@ SFILES=	$(srcdir)/gdbreplay.c $(srcdir)/inferiors.c $(srcdir)/dll.c \
 	$(srcdir)/common/filestuff.c $(srcdir)/target/waitstatus.c \
 	$(srcdir)/nat/mips-linux-watch.c $(srcdir)/common/print-utils.c \
 	$(srcdir)/common/rsp-low.c $(srcdir)/common/errors.c \
-	$(srcdir)/common/common-debug.c $(srcdir)/common/cleanups.c
+	$(srcdir)/common/common-debug.c $(srcdir)/common/cleanups.c \
+	$(srcdir)/common/common-exceptions.c
 
 DEPFILES = @GDBSERVER_DEPFILES@
 
@@ -184,6 +185,7 @@ OBS = agent.o ax.o inferiors.o regcache.o remote-utils.o server.o signals.o \
       mem-break.o hostio.o event-loop.o tracepoint.o xml-utils.o \
       common-utils.o ptid.o buffer.o format.o filestuff.o dll.o notif.o \
       tdesc.o print-utils.o rsp-low.o errors.o common-debug.o cleanups.o \
+      common-exceptions.o \
       $(XML_BUILTIN) $(DEPFILES) $(LIBOBJS)
 GDBREPLAY_OBS = gdbreplay.o version.o
 GDBSERVER_LIBS = @GDBSERVER_LIBS@
@@ -547,6 +549,9 @@ common-debug.o: ../common/common-debug.c
 cleanups.o: ../common/cleanups.c
 	$(COMPILE) $<
 	$(POSTCOMPILE)
+common-exceptions.o: ../common/common-exceptions.c
+	$(COMPILE) $<
+	$(POSTCOMPILE)
 waitstatus.o: ../target/waitstatus.c
 	$(COMPILE) $<
 	$(POSTCOMPILE)
diff --git a/gdb/gdbserver/utils.c b/gdb/gdbserver/utils.c
index 3ec4add..6283877 100644
--- a/gdb/gdbserver/utils.c
+++ b/gdb/gdbserver/utils.c
@@ -160,3 +160,11 @@ pfildes (gdb_fildes_t fd)
   return plongest (fd);
 #endif
 }
+
+/* See common/common-exceptions.h.  */
+
+void
+prepare_to_throw_exception (void)
+{
+  /* No client-specific actions required.  */
+}
-- 
1.7.1


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

* [PATCH 5/5] Use exceptions and cleanups in gdbserver
  2014-08-18  8:47 [PATCH 0/5] Make gdbserver use exceptions and cleanups Gary Benson
                   ` (3 preceding siblings ...)
  2014-08-18  8:52 ` [PATCH 4/5] Introduce common/common-exceptions.[ch] Gary Benson
@ 2014-08-18  9:25 ` Gary Benson
  2014-08-28 15:35   ` Pedro Alves
  2014-08-28 15:39 ` [PATCH 0/5] Make gdbserver use exceptions and cleanups Pedro Alves
  5 siblings, 1 reply; 14+ messages in thread
From: Gary Benson @ 2014-08-18  9:25 UTC (permalink / raw)
  To: gdb-patches

This commit replaces the hacky "exception" system in gdbserver with
the exceptions and cleanups subsystem from GDB.

Only the catch/cleanup code in what was "main" has been updated to
use the new system.  Other parts of gdbserver could likely be
converted to TRY_CATCH and cleanups too, but that can be done on an
as-needed basis if this patch is accepted.

A side-effect of this patch is that some error messages will change
slightly, and in cases with multiple errors the error messages will
be printed in a different order.

gdb/gdbserver/
2014-08-18  Gary Benson  <gbenson@redhat.com>

	* server.h (setjmp.h): Do not include.
	(toplevel): Do not declare.
	* server.c (common-exceptions.h): Include.
	(cleanups.h): Likewise.
	(toplevel): Do not define.
	(exit_code): New static global.
	(detach_or_kill_for_exit_cleanup): New function.
	(main): New function.  Original main renamed to...
	(captured_main): New function.
	* utils.c (common-exceptions.h): Include.
	(verror) [!IN_PROCESS_AGENT]: Use throw_verror.
---
 gdb/gdbserver/ChangeLog |   14 ++++
 gdb/gdbserver/server.c  |  196 ++++++++++++++++++++++++++---------------------
 gdb/gdbserver/server.h  |    4 -
 gdb/gdbserver/utils.c   |   11 +--
 4 files changed, 127 insertions(+), 98 deletions(-)

diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c
index 500260c..aec70f0 100644
--- a/gdb/gdbserver/server.c
+++ b/gdb/gdbserver/server.c
@@ -35,6 +35,8 @@
 #include "tracepoint.h"
 #include "dll.h"
 #include "hostio.h"
+#include "common-exceptions.h"
+#include "cleanups.h"
 
 /* The thread set with an `Hc' packet.  `Hc' is deprecated in favor of
    `vCont'.  Note the multi-process extensions made `vCont' a
@@ -73,8 +75,6 @@ int pass_signals[GDB_SIGNAL_LAST];
 int program_signals[GDB_SIGNAL_LAST];
 int program_signals_p;
 
-jmp_buf toplevel;
-
 /* The PID of the originally created or attached inferior.  Used to
    send signals to the process when GDB sends us an asynchronous interrupt
    (user hitting Control-C in the client), and to wait for the child to exit
@@ -3010,8 +3010,34 @@ detach_or_kill_for_exit (void)
   for_each_inferior (&all_processes, detach_or_kill_inferior_callback);
 }
 
-int
-main (int argc, char *argv[])
+/* Value that will be passed to exit(3) when gdbserver exits.  */
+static int exit_code;
+
+/* Cleanup version of detach_or_kill_for_exit.  */
+
+static void
+detach_or_kill_for_exit_cleanup (void *ignore)
+{
+  volatile struct gdb_exception exception;
+
+  TRY_CATCH (exception, RETURN_MASK_ALL)
+    {
+      detach_or_kill_for_exit ();
+    }
+
+  if (exception.reason < 0)
+    {
+      fflush (stdout);
+      fprintf (stderr, "Detach or kill failed: %s\n", exception.message);
+      exit_code = 1;
+    }
+}
+
+/* Main function.  This is called by the real "main" function,
+   wrapped in a TRY_CATCH that handles any uncaught exceptions.  */
+
+static void ATTRIBUTE_NORETURN
+captured_main (int argc, char *argv[])
 {
   int bad_attach;
   int pid;
@@ -3135,12 +3161,6 @@ main (int argc, char *argv[])
       continue;
     }
 
-  if (setjmp (toplevel))
-    {
-      fprintf (stderr, "Exiting\n");
-      exit (1);
-    }
-
   port = *next_arg;
   next_arg++;
   if (port == NULL || (!attach && !multi_mode && *next_arg == NULL))
@@ -3223,6 +3243,7 @@ main (int argc, char *argv[])
       last_status.value.integer = 0;
       last_ptid = minus_one_ptid;
     }
+  make_cleanup (detach_or_kill_for_exit_cleanup, NULL);
 
   initialize_notif ();
 
@@ -3231,19 +3252,6 @@ main (int argc, char *argv[])
      shared library event" notice on gdb side.  */
   dlls_changed = 0;
 
-  if (setjmp (toplevel))
-    {
-      /* If something fails and longjmps while detaching or killing
-	 inferiors, we'd end up here again, stuck in an infinite loop
-	 trap.  Be sure that if that happens, we exit immediately
-	 instead.  */
-      if (setjmp (toplevel) == 0)
-	detach_or_kill_for_exit ();
-      else
-	fprintf (stderr, "Detach or kill failed.  Exiting\n");
-      exit (1);
-    }
-
   if (last_status.kind == TARGET_WAITKIND_EXITED
       || last_status.kind == TARGET_WAITKIND_SIGNALLED)
     was_running = 0;
@@ -3251,13 +3259,12 @@ main (int argc, char *argv[])
     was_running = 1;
 
   if (!was_running && !multi_mode)
-    {
-      fprintf (stderr, "No program to debug.  GDBserver exiting.\n");
-      exit (1);
-    }
+    error ("No program to debug");
 
   while (1)
     {
+      volatile struct gdb_exception exception;
+
       noack_mode = 0;
       multi_process = 0;
       /* Be sure we're out of tfind mode.  */
@@ -3265,82 +3272,97 @@ main (int argc, char *argv[])
 
       remote_open (port);
 
-      if (setjmp (toplevel) != 0)
+      TRY_CATCH (exception, RETURN_MASK_ERROR)
 	{
-	  /* An error occurred.  */
-	  if (response_needed)
-	    {
-	      write_enn (own_buf);
-	      putpkt (own_buf);
-	    }
-	}
-
-      /* Wait for events.  This will return when all event sources are
-	 removed from the event loop.  */
-      start_event_loop ();
+	  /* Wait for events.  This will return when all event sources
+	     are removed from the event loop.  */
+	  start_event_loop ();
 
-      /* If an exit was requested (using the "monitor exit" command),
-	 terminate now.  The only other way to get here is for
-	 getpkt to fail; close the connection and reopen it at the
-	 top of the loop.  */
+	  /* If an exit was requested (using the "monitor exit"
+	     command), terminate now.  The only other way to get
+	     here is for getpkt to fail; close the connection
+	     and reopen it at the top of the loop.  */
 
-      if (exit_requested || run_once)
-	{
-	  /* If something fails and longjmps while detaching or
-	     killing inferiors, we'd end up here again, stuck in an
-	     infinite loop trap.  Be sure that if that happens, we
-	     exit immediately instead.  */
-	  if (setjmp (toplevel) == 0)
-	    {
-	      detach_or_kill_for_exit ();
-	      exit (0);
-	    }
-	  else
-	    {
-	      fprintf (stderr, "Detach or kill failed.  Exiting\n");
-	      exit (1);
-	    }
-	}
+	  if (exit_requested || run_once)
+	    throw_quit ("Quit");
 
-      fprintf (stderr,
-	       "Remote side has terminated connection.  "
-	       "GDBserver will reopen the connection.\n");
+	  fprintf (stderr,
+		   "Remote side has terminated connection.  "
+		   "GDBserver will reopen the connection.\n");
 
-      /* Get rid of any pending statuses.  An eventual reconnection
-	 (by the same GDB instance or another) will refresh all its
-	 state from scratch.  */
-      discard_queued_stop_replies (-1);
-      for_each_inferior (&all_threads, clear_pending_status_callback);
+	  /* Get rid of any pending statuses.  An eventual reconnection
+	     (by the same GDB instance or another) will refresh all its
+	     state from scratch.  */
+	  discard_queued_stop_replies (-1);
+	  for_each_inferior (&all_threads,
+			     clear_pending_status_callback);
 
-      if (tracing)
-	{
-	  if (disconnected_tracing)
+	  if (tracing)
 	    {
-	      /* Try to enable non-stop/async mode, so we we can both
-		 wait for an async socket accept, and handle async
-		 target events simultaneously.  There's also no point
-		 either in having the target always stop all threads,
-		 when we're going to pass signals down without
-		 informing GDB.  */
-	      if (!non_stop)
+	      if (disconnected_tracing)
 		{
-		  if (start_non_stop (1))
-		    non_stop = 1;
+		  /* Try to enable non-stop/async mode, so we we can
+		     both wait for an async socket accept, and handle
+		     async target events simultaneously.  There's also
+		     no point either in having the target always stop
+		     all threads, when we're going to pass signals
+		     down without informing GDB.  */
+		  if (!non_stop)
+		    {
+		      if (start_non_stop (1))
+			non_stop = 1;
 
-		  /* Detaching implicitly resumes all threads; simply
-		     disconnecting does not.  */
+		      /* Detaching implicitly resumes all threads;
+			 simply disconnecting does not.  */
+		    }
+		}
+	      else
+		{
+		  fprintf (stderr,
+			   "Disconnected tracing disabled; "
+			   "stopping trace run.\n");
+		  stop_tracing ();
 		}
 	    }
-	  else
+	}
+
+      if (exception.reason == RETURN_ERROR)
+	{
+	  if (response_needed)
 	    {
-	      fprintf (stderr,
-		       "Disconnected tracing disabled; stopping trace run.\n");
-	      stop_tracing ();
+	      write_enn (own_buf);
+	      putpkt (own_buf);
 	    }
 	}
     }
 }
 
+/* Main function.  */
+
+int
+main (int argc, char *argv[])
+{
+  volatile struct gdb_exception exception;
+
+  TRY_CATCH (exception, RETURN_MASK_ALL)
+    {
+      captured_main (argc, argv);
+    }
+
+  /* captured_main should never return.  */
+  gdb_assert (exception.reason < 0);
+
+  if (exception.reason == RETURN_ERROR)
+    {
+      fflush (stdout);
+      fprintf (stderr, "%s\n", exception.message);
+      fprintf (stderr, "Exiting\n");
+      exit_code = 1;
+    }
+
+  exit (exit_code);
+}
+
 /* Skip PACKET until the next semi-colon (or end of string).  */
 
 static void
diff --git a/gdb/gdbserver/server.h b/gdb/gdbserver/server.h
index 97498a6..cac73e9 100644
--- a/gdb/gdbserver/server.h
+++ b/gdb/gdbserver/server.h
@@ -29,8 +29,6 @@ gdb_static_assert (sizeof (CORE_ADDR) >= sizeof (void *));
 
 #include "version.h"
 
-#include <setjmp.h>
-
 #ifdef HAVE_ALLOCA_H
 #include <alloca.h>
 #endif
@@ -88,8 +86,6 @@ extern int pass_signals[];
 extern int program_signals[];
 extern int program_signals_p;
 
-extern jmp_buf toplevel;
-
 extern int disable_packet_vCont;
 extern int disable_packet_Tthread;
 extern int disable_packet_qC;
diff --git a/gdb/gdbserver/utils.c b/gdb/gdbserver/utils.c
index 6283877..e2eb4f4 100644
--- a/gdb/gdbserver/utils.c
+++ b/gdb/gdbserver/utils.c
@@ -17,6 +17,7 @@
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "server.h"
+#include "common-exceptions.h"
 
 #ifdef IN_PROCESS_AGENT
 #  define PREFIX "ipa: "
@@ -76,17 +77,13 @@ perror_with_name (const char *string)
 void
 verror (const char *string, va_list args)
 {
-#ifndef IN_PROCESS_AGENT
-  extern jmp_buf toplevel;
-#endif
-
+#ifdef IN_PROCESS_AGENT
   fflush (stdout);
   vfprintf (stderr, string, args);
   fprintf (stderr, "\n");
-#ifndef IN_PROCESS_AGENT
-  longjmp (toplevel, 1);
-#else
   exit (1);
+#else
+  throw_verror (GENERIC_ERROR, string, args);
 #endif
 }
 
-- 
1.7.1


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

* Re: [PATCH 2/5] Move cleanups.[ch] to common
  2014-08-18  8:47 ` [PATCH 2/5] Move cleanups.[ch] to common Gary Benson
@ 2014-08-20 16:47   ` Pedro Alves
  2014-08-20 19:05     ` Gary Benson
  2014-08-28 15:35   ` Pedro Alves
  2014-08-28 15:36   ` Pedro Alves
  2 siblings, 1 reply; 14+ messages in thread
From: Pedro Alves @ 2014-08-20 16:47 UTC (permalink / raw)
  To: Gary Benson, gdb-patches

On 08/18/2014 09:46 AM, Gary Benson wrote:
> This commit moves cleanups.[ch] into gdb/common/.  The only change to
> the content of the files is that cleanups.c's include list was altered
> to match its new location.

Please send a 'git diff -M' version.

Thanks,
Pedro Alves


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

* Re: [PATCH 3/5] Introduce common/gdb_setjmp.h
  2014-08-18  8:47 ` [PATCH 3/5] Introduce common/gdb_setjmp.h Gary Benson
@ 2014-08-20 16:54   ` Pedro Alves
  0 siblings, 0 replies; 14+ messages in thread
From: Pedro Alves @ 2014-08-20 16:54 UTC (permalink / raw)
  To: Gary Benson, gdb-patches

On 08/18/2014 09:46 AM, Gary Benson wrote:
> This commit creates a new file, common/gdb_setjmp.h, to hold some
> portability macros for setjmp/longjmp et al. that are used by the
> exceptions subsystem and by the demangler crash catcher.

Looks like this one stands on its own.

OK, with ...

> 
> gdb/
> 2014-08-18  Gary Benson  <gbenson@redhat.com>
> 
> 	* common/gdb_setjmp.h: New file.
> 	* Makefile.in (HFILES_NO_SRCDIR): Add common/gdb_setjmp.h.
> 	* configure.ac: Move sigsetjmp check...
> 	* common/common.m4: ...here.
> 	* configure: Regenerate.
> 	* cp-support.c (SIGJMP_BUF): Undefine.

... please say "Delete.".  "Undefine" makes the reader expect
an #undef.

> 	(SIGSETJMP): Likewise.
> 	(SIGLONGJMP): Likewise.
> 	* exceptions.h (gdb_setjmp.h): Include.
> 	(setjmp.h): Do not include.
> 	(EXCEPTIONS_SIGJMP_BUF): Undefine.

Likewise.

> 	(EXCEPTIONS_SIGSETJMP): Likewise.
> 	(EXCEPTIONS_SIGLONGJMP): Likewise.
> 	Replace all uses of EXCEPTIONS_SIG* macros with SIG* macros
> 	from gdb_setjmp.h.
> 	* exceptions.c: Likewise.

> 
> gdb/gdbserver/
> 2014-08-18  Gary Benson  <gbenson@redhat.com>
> 
> 	* config.in: Regenerate.
> 	* configure: Likewise.


Thanks,
Pedro Alves


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

* Re: [PATCH 2/5] Move cleanups.[ch] to common
  2014-08-20 16:47   ` Pedro Alves
@ 2014-08-20 19:05     ` Gary Benson
  0 siblings, 0 replies; 14+ messages in thread
From: Gary Benson @ 2014-08-20 19:05 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb-patches

Pedro Alves wrote:
> On 08/18/2014 09:46 AM, Gary Benson wrote:
> > This commit moves cleanups.[ch] into gdb/common/.  The only change
> > to the content of the files is that cleanups.c's include list was
> > altered to match its new location.
> 
> Please send a 'git diff -M' version.

Sure:

--
diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index e68798d..1840ce7 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -794,7 +794,7 @@ SFILES = ada-exp.y ada-lang.c ada-typeprint.c ada-valprint.c ada-tasks.c \
 	breakpoint.c break-catch-sig.c break-catch-throw.c \
 	build-id.c buildsym.c \
 	c-exp.y c-lang.c c-typeprint.c c-valprint.c c-varobj.c \
-	charset.c cleanups.c cli-out.c coffread.c coff-pe-read.c \
+	charset.c common/cleanups.c cli-out.c coffread.c coff-pe-read.c \
 	complaints.c completer.c continuations.c corefile.c corelow.c \
 	cp-abi.c cp-support.c cp-namespace.c cp-valprint.c \
 	d-exp.y d-lang.c d-support.c d-valprint.c \
@@ -885,7 +885,7 @@ objfiles.h common/vec.h disasm.h mips-tdep.h ser-base.h \
 gdb_curses.h bfd-target.h memattr.h inferior.h ax.h dummy-frame.h \
 inflow.h fbsd-nat.h ia64-libunwind-tdep.h completer.h inf-ttrace.h \
 solib-target.h gdb_vfork.h alpha-tdep.h dwarf2expr.h \
-m2-lang.h stack.h charset.h cleanups.h addrmap.h command.h solist.h source.h \
+m2-lang.h stack.h charset.h addrmap.h command.h solist.h source.h \
 target.h target-dcache.h prologue-value.h cp-abi.h tui/tui-hooks.h tui/tui.h \
 tui/tui-file.h tui/tui-command.h tui/tui-disasm.h tui/tui-wingeneral.h \
 tui/tui-windata.h tui/tui-data.h tui/tui-win.h tui/tui-stack.h \
@@ -938,6 +938,8 @@ target/wait.h target/waitstatus.h nat/linux-nat.h nat/linux-waitpid.h \
 common/print-utils.h common/rsp-low.h nat/i386-dregs.h x86-linux-nat.h \
 i386-linux-nat.h common/common-defs.h common/errors.h common/common-types.h \
 common/common-debug.h target/target.h target/symbol.h common/common-regcache.h
+common/common-debug.h target/target.h target/symbol.h common/common-regcache.h \
+common/cleanups.h
 
 # Header files that already have srcdir in them, or which are in objdir.
 
@@ -2154,6 +2156,10 @@ common-debug.o: ${srcdir}/common/common-debug.c
 	$(COMPILE) $(srcdir)/common/common-debug.c
 	$(POSTCOMPILE)
 
+cleanups.o: ${srcdir}/common/cleanups.c
+	$(COMPILE) $(srcdir)/common/cleanups.c
+	$(POSTCOMPILE)
+
 #
 # gdb/target/ dependencies
 #
diff --git a/gdb/cleanups.c b/gdb/common/cleanups.c
similarity index 99%
rename from gdb/cleanups.c
rename to gdb/common/cleanups.c
index ddf8e5b..49b643b 100644
--- a/gdb/cleanups.c
+++ b/gdb/common/cleanups.c
@@ -17,7 +17,8 @@
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
-#include "defs.h"
+#include "common-defs.h"
+#include "cleanups.h"
 
 /* The cleanup list records things that have to be undone
    if an error happens (descriptors to be closed, memory to be freed, etc.)
diff --git a/gdb/cleanups.h b/gdb/common/cleanups.h
similarity index 100%
rename from gdb/cleanups.h
rename to gdb/common/cleanups.h
diff --git a/gdb/gdbserver/Makefile.in b/gdb/gdbserver/Makefile.in
index 18486c6..f130082 100644
--- a/gdb/gdbserver/Makefile.in
+++ b/gdb/gdbserver/Makefile.in
@@ -170,7 +170,7 @@ SFILES=	$(srcdir)/gdbreplay.c $(srcdir)/inferiors.c $(srcdir)/dll.c \
 	$(srcdir)/common/filestuff.c $(srcdir)/target/waitstatus.c \
 	$(srcdir)/nat/mips-linux-watch.c $(srcdir)/common/print-utils.c \
 	$(srcdir)/common/rsp-low.c $(srcdir)/common/errors.c \
-	$(srcdir)/common/common-debug.c
+	$(srcdir)/common/common-debug.c $(srcdir)/common/cleanups.c
 
 DEPFILES = @GDBSERVER_DEPFILES@
 
@@ -183,7 +183,7 @@ OBS = agent.o ax.o inferiors.o regcache.o remote-utils.o server.o signals.o \
       target.o waitstatus.o utils.o debug.o version.o vec.o gdb_vecs.o \
       mem-break.o hostio.o event-loop.o tracepoint.o xml-utils.o \
       common-utils.o ptid.o buffer.o format.o filestuff.o dll.o notif.o \
-      tdesc.o print-utils.o rsp-low.o errors.o common-debug.o \
+      tdesc.o print-utils.o rsp-low.o errors.o common-debug.o cleanups.o \
       $(XML_BUILTIN) $(DEPFILES) $(LIBOBJS)
 GDBREPLAY_OBS = gdbreplay.o version.o
 GDBSERVER_LIBS = @GDBSERVER_LIBS@
@@ -544,6 +544,9 @@ errors.o: ../common/errors.c
 common-debug.o: ../common/common-debug.c
 	$(COMPILE) $<
 	$(POSTCOMPILE)
+cleanups.o: ../common/cleanups.c
+	$(COMPILE) $<
+	$(POSTCOMPILE)
 waitstatus.o: ../target/waitstatus.c
 	$(COMPILE) $<
 	$(POSTCOMPILE)


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

* Re: [PATCH 2/5] Move cleanups.[ch] to common
  2014-08-18  8:47 ` [PATCH 2/5] Move cleanups.[ch] to common Gary Benson
  2014-08-20 16:47   ` Pedro Alves
@ 2014-08-28 15:35   ` Pedro Alves
  2014-08-28 15:36   ` Pedro Alves
  2 siblings, 0 replies; 14+ messages in thread
From: Pedro Alves @ 2014-08-28 15:35 UTC (permalink / raw)
  To: Gary Benson, gdb-patches

On 08/18/2014 09:46 AM, Gary Benson wrote:
> @@ -938,6 +938,8 @@ target/wait.h target/waitstatus.h nat/linux-nat.h nat/linux-waitpid.h \
>  common/print-utils.h common/rsp-low.h nat/i386-dregs.h x86-linux-nat.h \
>  i386-linux-nat.h common/common-defs.h common/errors.h common/common-types.h \
>  common/common-debug.h target/target.h target/symbol.h common/common-regcache.h
> +common/common-debug.h target/target.h target/symbol.h common/common-regcache.h \
> +common/cleanups.h

Note, this breaks the build.  The

 common/common-debug.h target/target.h target/symbol.h common/common-regcache.h

line should have been removed.

Thanks,
Pedro Alves


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

* Re: [PATCH 5/5] Use exceptions and cleanups in gdbserver
  2014-08-18  9:25 ` [PATCH 5/5] Use exceptions and cleanups in gdbserver Gary Benson
@ 2014-08-28 15:35   ` Pedro Alves
  0 siblings, 0 replies; 14+ messages in thread
From: Pedro Alves @ 2014-08-28 15:35 UTC (permalink / raw)
  To: Gary Benson, gdb-patches

On 08/18/2014 09:46 AM, Gary Benson wrote:

> diff --git a/gdb/gdbserver/server.h b/gdb/gdbserver/server.h
> index 97498a6..cac73e9 100644
> diff --git a/gdb/gdbserver/utils.c b/gdb/gdbserver/utils.c
> index 6283877..e2eb4f4 100644
> --- a/gdb/gdbserver/utils.c
> +++ b/gdb/gdbserver/utils.c
> @@ -17,6 +17,7 @@
>     along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
>  
>  #include "server.h"
> +#include "common-exceptions.h"
>  

...

> diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c
> index 500260c..aec70f0 100644
> --- a/gdb/gdbserver/server.c
> +++ b/gdb/gdbserver/server.c
> @@ -35,6 +35,8 @@
>  #include "tracepoint.h"
>  #include "dll.h"
>  #include "hostio.h"
> +#include "common-exceptions.h"
> +#include "cleanups.h"

We'll want to start using exceptions/cleanups everywhere.
We'll no doubt end up including them from a central place, either
server.h or somewhere in common/.  I think we should just put
them in server.h already ...

> --- a/gdb/gdbserver/server.h
> +++ b/gdb/gdbserver/server.h
> @@ -29,8 +29,6 @@ gdb_static_assert (sizeof (CORE_ADDR) >= sizeof (void *));
>
>  #include "version.h"
>
> -#include <setjmp.h>
> -
>  #ifdef HAVE_ALLOCA_H
>  #include <alloca.h>
>  #endif
> @@ -88,8 +86,6 @@ extern int pass_signals[];
>  extern int program_signals[];
>  extern int program_signals_p;
>
> -extern jmp_buf toplevel;
> -
>  extern int disable_packet_vCont;
>  extern int disable_packet_Tthread;
>  extern int disable_packet_qC;

... which is the same place we had the bare bones setjmp stuff,
avoiding the sprinkling-includes-around-only-to-inevitably-remove-them-later.
This way, even if we move them somewhere in common/ at some point, we'll
still have only a single place to touch.

Other than that, looks good.

Thanks,
Pedro Alves


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

* Re: [PATCH 2/5] Move cleanups.[ch] to common
  2014-08-18  8:47 ` [PATCH 2/5] Move cleanups.[ch] to common Gary Benson
  2014-08-20 16:47   ` Pedro Alves
  2014-08-28 15:35   ` Pedro Alves
@ 2014-08-28 15:36   ` Pedro Alves
  2 siblings, 0 replies; 14+ messages in thread
From: Pedro Alves @ 2014-08-28 15:36 UTC (permalink / raw)
  To: Gary Benson, gdb-patches

Hi Gary,

On 08/18/2014 09:46 AM, Gary Benson wrote:
> gdb/
> 2014-08-18  Gary Benson  <gbenson@redhat.com>
> 
> 	* cleanups.h: Moved to...
> 	* common/cleanups.h: New file.
> 	* cleanups.c: Moved to...
> 	* common/cleanups.c: New file.

> --- a/gdb/cleanups.c
> +++ b/gdb/common/cleanups.c
> @@ -17,7 +17,8 @@
>     You should have received a copy of the GNU General Public License
>     along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
>
> -#include "defs.h"
> +#include "common-defs.h"
> +#include "cleanups.h"

The new cleanups.h inclusion should be mentioned in the ChangeLog as well.

> 	* Makefile.in (SFILES): Replace cleanups.c with common/cleanups.c.
> 	(HFILES_NO_SRCDIR): Replace cleanups.h with common/cleanups.h.
> 	(cleanups.o): New rule.

Thanks,
Pedro Alves


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

* Re: [PATCH 0/5] Make gdbserver use exceptions and cleanups
  2014-08-18  8:47 [PATCH 0/5] Make gdbserver use exceptions and cleanups Gary Benson
                   ` (4 preceding siblings ...)
  2014-08-18  9:25 ` [PATCH 5/5] Use exceptions and cleanups in gdbserver Gary Benson
@ 2014-08-28 15:39 ` Pedro Alves
  2014-08-29 10:07   ` Gary Benson
  5 siblings, 1 reply; 14+ messages in thread
From: Pedro Alves @ 2014-08-28 15:39 UTC (permalink / raw)
  To: Gary Benson, gdb-patches

On 08/18/2014 09:46 AM, Gary Benson wrote:

> gdbserver has the rudiments of an exception system, but it's kind of
> hacky.  This series converts gdbserver to use the same exceptions and
> cleanups as GDB.
> 
> This series is fairly minimal in that only the catch/cleanup code in
> what was "main" has been updated to use the new system.  Other parts
> of gdbserver could likely be converted to TRY_CATCH and cleanups too,
> but that can be done on an as-needed basis if this patch is accepted.
> 
> A side-effect of this patch is that some error messages will change
> slightly, and in cases with multiple errors the error messages will
> be printed in a different order.
> 
> Built and regtested on RHEL 6.5 x86_64.
> 
> Ok to commit?

Other than the minor nits I just picked in the responses to the
patches, this looks great to me.

Thanks a lot for doing this.

Pedro Alves


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

* Re: [PATCH 0/5] Make gdbserver use exceptions and cleanups
  2014-08-28 15:39 ` [PATCH 0/5] Make gdbserver use exceptions and cleanups Pedro Alves
@ 2014-08-29 10:07   ` Gary Benson
  0 siblings, 0 replies; 14+ messages in thread
From: Gary Benson @ 2014-08-29 10:07 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb-patches

Pedro Alves wrote:
> On 08/18/2014 09:46 AM, Gary Benson wrote:
> > gdbserver has the rudiments of an exception system, but it's
> > kind of hacky.  This series converts gdbserver to use the
> > same exceptions and cleanups as GDB.
> > 
> > This series is fairly minimal in that only the catch/cleanup code
> > in what was "main" has been updated to use the new system.  Other
> > parts of gdbserver could likely be converted to TRY_CATCH and
> > cleanups too, but that can be done on an as-needed basis if this
> > patch is accepted.
> > 
> > A side-effect of this patch is that some error messages will
> > change slightly, and in cases with multiple errors the error
> > messages will be printed in a different order.
> > 
> > Built and regtested on RHEL 6.5 x86_64.
> > 
> > Ok to commit?
> 
> Other than the minor nits I just picked in the responses to the
> patches, this looks great to me.
> 
> Thanks a lot for doing this.

No problem, thanks for the review :)

I've pushed this with the changes you suggested.

common-exceptions.h and cleanups.h are now included in server.h.
They're not global includes in GDB, but I could put together a
patch making them so if you like?  Let me know...

Thanks,
Gary

-- 
http://gbenson.net/


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

end of thread, other threads:[~2014-08-29 10:07 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-08-18  8:47 [PATCH 0/5] Make gdbserver use exceptions and cleanups Gary Benson
2014-08-18  8:47 ` [PATCH 2/5] Move cleanups.[ch] to common Gary Benson
2014-08-20 16:47   ` Pedro Alves
2014-08-20 19:05     ` Gary Benson
2014-08-28 15:35   ` Pedro Alves
2014-08-28 15:36   ` Pedro Alves
2014-08-18  8:47 ` [PATCH 1/5] Move internal_{,v}warning to common/errors.[ch] Gary Benson
2014-08-18  8:47 ` [PATCH 3/5] Introduce common/gdb_setjmp.h Gary Benson
2014-08-20 16:54   ` Pedro Alves
2014-08-18  8:52 ` [PATCH 4/5] Introduce common/common-exceptions.[ch] Gary Benson
2014-08-18  9:25 ` [PATCH 5/5] Use exceptions and cleanups in gdbserver Gary Benson
2014-08-28 15:35   ` Pedro Alves
2014-08-28 15:39 ` [PATCH 0/5] Make gdbserver use exceptions and cleanups Pedro Alves
2014-08-29 10:07   ` Gary Benson

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