Blob Blame History Raw
From 3bd7e5b7ee5ea0b3bbb4030ca841f66faad74f0f Mon Sep 17 00:00:00 2001
From: Sergio Durigan Junior <sergiodj@redhat.com>
Date: Fri, 21 Aug 2015 18:28:07 -0400
Subject: [PATCH 2/4] Catching errors on probes-based dynamic linker interface

This patch is intended to make the interaction between the
probes-based dynamic linker interface and the SystemTap SDT probe code
on GDB more robust.  It does that by wrapping the calls to the probe
API with TRY...CATCH'es, so that any exception thrown will be caught
and handled properly.

The idea for this patch came from
<https://bugzilla.redhat.com/show_bug.cgi?id=1196181>, which is a bug
initially filed against Fedora GDB (but now under Fedora GLIBC).  This
bug happens on armhfp (although it could happen on other targets as
well), and is triggered because GCC generates a strange argument for
one of the probes used by GDB in the dynamic linker interface.  As can
be seen in the bug, this argument is "-4@.L1052".

I don't want to discuss the reasons for this argument to be there
(this discussion belongs to the bug, or to another thread), but GDB
could definitely do a better error handling here.  Currently, one sees
the following message when there is an error in the probes-based
dynamic linker interface:

  (gdb) run
  Starting program: /bin/inferior
  warning: Probes-based dynamic linker interface failed.
  Reverting to original interface.

  Cannot parse expression `.L976 4@r4'.
  (gdb)

Which means that one needs to explicitly issue a "continue" command to
make GDB continue running the inferior, even though this error is not
fatal and GDB will fallback to the old interface automatically.

This is where this patch helps: it makes GDB still print the necessary
warnings or error messages, but it *also* does not stop the inferior
unnecessarily.

I have tested this patch on the systems where this error happens, but
I could not come up with a way to create a testcase for it.
Nevertheless, it should be straightforward to see that this patch does
improve the current situation.

gdb/ChangeLog:
2015-09-01  Sergio Durigan Junior  <sergiodj@redhat.com>

	* solib-svr4.c (solib_event_probe_action): Call
	get_probe_argument_count using TRY...CATCH.
	(svr4_handle_solib_event): Likewise, for evaluate_probe_argument.
---
 gdb/ChangeLog    |  6 ++++++
 gdb/solib-svr4.c | 43 ++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 46 insertions(+), 3 deletions(-)

Index: gdb-7.10/gdb/solib-svr4.c
===================================================================
--- gdb-7.10.orig/gdb/solib-svr4.c
+++ gdb-7.10/gdb/solib-svr4.c
@@ -1796,7 +1796,23 @@ solib_event_probe_action (struct probe_a
        arg0: Lmid_t lmid (mandatory)
        arg1: struct r_debug *debug_base (mandatory)
        arg2: struct link_map *new (optional, for incremental updates)  */
-  probe_argc = get_probe_argument_count (pa->probe, frame);
+  TRY
+    {
+      probe_argc = get_probe_argument_count (pa->probe, frame);
+    }
+  CATCH (ex, RETURN_MASK_ERROR)
+    {
+      exception_print (gdb_stderr, ex);
+      probe_argc = 0;
+    }
+  END_CATCH
+
+  /* If get_probe_argument_count throws an exception, probe_argc will
+     be set to zero.  However, if pa->probe does not have arguments,
+     then get_probe_argument_count will succeed but probe_argc will
+     also be zero.  Both cases happen because of different things, but
+     they are treated equally here: action will be set to
+     PROBES_INTERFACE_FAILED.  */
   if (probe_argc == 2)
     action = FULL_RELOAD;
   else if (probe_argc < 2)
@@ -1950,7 +1966,17 @@ svr4_handle_solib_event (void)
   usm_chain = make_cleanup (resume_section_map_updates_cleanup,
 			    current_program_space);
 
-  val = evaluate_probe_argument (pa->probe, 1, frame);
+  TRY
+    {
+      val = evaluate_probe_argument (pa->probe, 1, frame);
+    }
+  CATCH (ex, RETURN_MASK_ERROR)
+    {
+      exception_print (gdb_stderr, ex);
+      val = NULL;
+    }
+  END_CATCH
+
   if (val == NULL)
     {
       do_cleanups (old_chain);
@@ -1981,7 +2007,18 @@ svr4_handle_solib_event (void)
 
   if (action == UPDATE_OR_RELOAD)
     {
-      val = evaluate_probe_argument (pa->probe, 2, frame);
+      TRY
+	{
+	  val = evaluate_probe_argument (pa->probe, 2, frame);
+	}
+      CATCH (ex, RETURN_MASK_ERROR)
+	{
+	  exception_print (gdb_stderr, ex);
+	  do_cleanups (old_chain);
+	  return;
+	}
+      END_CATCH
+
       if (val != NULL)
 	lm = value_as_address (val);
 
From ad1c917a79e8c5aa67657f148415c1bee01b240f Mon Sep 17 00:00:00 2001
From: Sergio Durigan Junior <sergiodj@redhat.com>
Date: Wed, 2 Sep 2015 00:34:22 -0400
Subject: [PATCH 3/4] Initialize variable and silence GCC warning from last
 commit

BuildBot e-mailed me to let me know that my last commit broke GDB on
RHEL-7.1 s390x.  On solib-svr4.c:svr4_handle_solib_event, 'val' now
needs to be initialized as NULL because it is inside a TRY..CATCH
block.  This patch does that.  Pushed as obvious.

gdb/ChangeLog:
2015-09-01  Sergio Durigan Junior  <sergiodj@redhat.com>

	* solib-svr4.c (svr4_handle_solib_event): Initialize 'val' as NULL
---
 gdb/ChangeLog    | 4 ++++
 gdb/solib-svr4.c | 2 +-
 2 files changed, 5 insertions(+), 1 deletion(-)

Index: gdb-7.10/gdb/solib-svr4.c
===================================================================
--- gdb-7.10.orig/gdb/solib-svr4.c
+++ gdb-7.10/gdb/solib-svr4.c
@@ -1918,7 +1918,7 @@ svr4_handle_solib_event (void)
   struct probe_and_action *pa;
   enum probe_action action;
   struct cleanup *old_chain, *usm_chain;
-  struct value *val;
+  struct value *val = NULL;
   CORE_ADDR pc, debug_base, lm = 0;
   int is_initial_ns;
   struct frame_info *frame = get_current_frame ();
From 73c6b4756a7cee53c274ed05fddcd079b8b7e57c Mon Sep 17 00:00:00 2001
From: Sergio Durigan Junior <sergiodj@redhat.com>
Date: Wed, 2 Sep 2015 00:46:43 -0400
Subject: [PATCH 4/4] Initialize yet another variable to silence GCC warning
 from last-but-one commit

Yet another BuildBot e-mail, yet another breakage on RHEL-7.1 s390x
(which uses an older GCC).  This time,
solib-svr4.c:solib_event_probe_action has the probe_argc variable,
which is now inside a TRY..CATCH and therefore needs to be
initialized.  Pushed as obvious.

gdb/ChangeLog:
2015-09-01  Sergio Durigan Junior  <sergiodj@redhat.com>

	* solib-svr4.c (solib_event_probe_action): Initialize 'probe_argc'
	as zero.
---
 gdb/ChangeLog    | 5 +++++
 gdb/solib-svr4.c | 2 +-
 2 files changed, 6 insertions(+), 1 deletion(-)

 2015-09-01  Sergio Durigan Junior  <sergiodj@redhat.com>
Index: gdb-7.10/gdb/solib-svr4.c
===================================================================
--- gdb-7.10.orig/gdb/solib-svr4.c
+++ gdb-7.10/gdb/solib-svr4.c
@@ -1782,7 +1782,7 @@ static enum probe_action
 solib_event_probe_action (struct probe_and_action *pa)
 {
   enum probe_action action;
-  unsigned probe_argc;
+  unsigned probe_argc = 0;
   struct frame_info *frame = get_current_frame ();
 
   action = pa->action;