This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH 1/2] Simply setting solib breakpoint in solib-dsbt.c


There is a regression on handling solib breakpoint in tic6x-uclinux
target.  In breakpoint.c:bpstat_stop_status:

  /* A bit of special processing for shlib breakpoints.  We need to
     process solib loading here, so that the lists of loaded and
     unloaded libraries are correct before we handle "catch load" and
     "catch unload".  */
  for (bs = bs_head; bs != NULL; bs = bs->next)
    {
      if (bs->breakpoint_at && bs->breakpoint_at->type == bp_shlib_event)
	{
	  handle_solib_event ();
	  break;
	}
    }

however, the solib breakpoint will be removed in the callees of
handle_solib_event, and the bs->breakpoint_at becomes dangling,
the backtrace is:
 #0  remove_solib_event_breakpoints () at ../../src/gdb-ti-c6x/gdb/breakpoint.c:7382
 #1  0x000000000045d357 in enable_break2 () at ../../src/gdb-ti-c6x/gdb/solib-dsbt.c:965
 #2  0x000000000045cdb9 in dsbt_current_sos () at ../../src/gdb-ti-c6x/gdb/solib-dsbt.c:757
 #3  0x000000000062b0e5 in update_solib_list (from_tty=from_tty@entry=0, target=<optimized out>) at ../../src/gdb-ti-c6x/gdb/solib.c:667
 #4  0x000000000062bd6f in solib_add (pattern=pattern@entry=0x0, from_tty=from_tty@entry=0, target=<optimized out>, readsyms=1)
    at ../../src/gdb-ti-c6x/gdb/solib.c:881
 #5  0x00000000004eca4c in handle_solib_event () at ../../src/gdb-ti-c6x/gdb/breakpoint.c:5376
 #6  0x00000000004ece19 in bpstat_stop_status (aspace=0xc37660, bp_addr=bp_addr@entry=3843066336, ptid=..., ws=ws@entry=0x7fffffffdf60)
    at ../../src/gdb-ti-c6x/gdb/breakpoint.c:5265

in tic6x, we firstly setting solib breakpoint on "_start", when this
breakpoint is hit, GDB removes this breakpoint and sets solib
breakpoint on somewhere else (on _dl_debug_state).  This can be
simplified by setting solib breakpoint on _dl_debug_state, like what
solib-svr4.c does, and GDB doesn't have to remove it.  Then the problem
of dangling breakpoint is fixed.

Regression tested on tic6x-uclinux.  I'll commit it in a couple of
days.

gdb:

2013-05-04  Yao Qi  <yao@codesourcery.com>

	* solib-dsbt.c (enable_break): Declare.
	(dsbt_current_sos): Remove call to enable_break2.
	(enable_break2): Rename to enable_break.  Set solib breakpoint
	on '_dl_debug_state'.
	(enable_break): Remove.
---
 gdb/solib-dsbt.c |  147 ++++++++++-------------------------------------------
 1 files changed, 28 insertions(+), 119 deletions(-)

diff --git a/gdb/solib-dsbt.c b/gdb/solib-dsbt.c
index b109772..ead18ba 100644
--- a/gdb/solib-dsbt.c
+++ b/gdb/solib-dsbt.c
@@ -408,7 +408,7 @@ fetch_loadmap (CORE_ADDR ldmaddr)
 }
 
 static void dsbt_relocate_main_executable (void);
-static int enable_break2 (void);
+static int enable_break (void);
 
 /* Scan for DYNTAG in .dynamic section of ABFD. If DYNTAG is found 1 is
    returned and the corresponding PTR is set.  */
@@ -754,8 +754,6 @@ dsbt_current_sos (void)
 					  sizeof (lm_buf.l_next), byte_order);
     }
 
-  enable_break2 ();
-
   return sos_head;
 }
 
@@ -795,30 +793,16 @@ cmp_name (asymbol *sym, void *data)
    for arranging for the inferior to hit a breakpoint after mapping in
    the shared libraries.  This function enables that breakpoint.
 
-   On the TIC6X, using the shared library (DSBT), the symbol
-   _dl_debug_addr points to the r_debug struct which contains
-   a field called r_brk.  r_brk is the address of the function
-   descriptor upon which a breakpoint must be placed.  Being a
-   function descriptor, we must extract the entry point in order
-   to set the breakpoint.
-
-   Our strategy will be to get the .interp section from the
-   executable.  This section will provide us with the name of the
-   interpreter.  We'll open the interpreter and then look up
-   the address of _dl_debug_addr.  We then relocate this address
-   using the interpreter's loadmap.  Once the relocated address
-   is known, we fetch the value (address) corresponding to r_brk
-   and then use that value to fetch the entry point of the function
-   we're interested in.  */
+   On the TIC6X, using the shared library (DSBT), GDB can try to place
+   a breakpoint on '_dl_debug_state' to monitor the shared library
+   event.  */
 
 static int
-enable_break2 (void)
+enable_break (void)
 {
   enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
-  int success = 0;
-  char **bkpt_namep;
   asection *interp_sect;
-  struct dsbt_info *info = get_dsbt_info ();
+  struct dsbt_info *info;
 
   if (exec_bfd == NULL)
     return 0;
@@ -826,6 +810,8 @@ enable_break2 (void)
   if (!target_has_execution)
     return 0;
 
+  info = get_dsbt_info ();
+
   if (info->enable_break2_done)
     return 1;
 
@@ -846,6 +832,7 @@ enable_break2 (void)
       gdb_byte addr_buf[TIC6X_PTR_SIZE];
       struct int_elf32_dsbt_loadmap *ldm;
       volatile struct gdb_exception ex;
+      int ret;
 
       /* Read the contents of the .interp section into a local buffer;
 	 the contents specify the dynamic linker this program uses.  */
@@ -895,81 +882,41 @@ enable_break2 (void)
 	    info->interp_plt_sect_low + bfd_section_size (tmp_bfd, interp_sect);
 	}
 
-      addr = gdb_bfd_lookup_symbol (tmp_bfd, cmp_name, "_dl_debug_addr");
-      if (addr == 0)
+      addr = gdb_bfd_lookup_symbol (tmp_bfd, cmp_name, "_dl_debug_state");
+      if (addr != 0)
 	{
-	  warning (_("Could not find symbol _dl_debug_addr in dynamic linker"));
-	  enable_break_failure_warning ();
-	  gdb_bfd_unref (tmp_bfd);
-	  return 0;
-	}
-
-      if (solib_dsbt_debug)
-	fprintf_unfiltered (gdb_stdlog,
-			    "enable_break: _dl_debug_addr (prior to relocation) = %s\n",
-			    hex_string_custom (addr, 8));
+	  if (solib_dsbt_debug)
+	    fprintf_unfiltered (gdb_stdlog,
+				"enable_break: _dl_debug_state (prior to relocation) = %s\n",
+				hex_string_custom (addr, 8));
+	  addr += displacement_from_map (ldm, addr);
 
-      addr += displacement_from_map (ldm, addr);
+	  if (solib_dsbt_debug)
+	    fprintf_unfiltered (gdb_stdlog,
+				"enable_break: _dl_debug_state (after relocation) = %s\n",
+				hex_string_custom (addr, 8));
 
-      if (solib_dsbt_debug)
-	fprintf_unfiltered (gdb_stdlog,
-			    "enable_break: _dl_debug_addr (after relocation) = %s\n",
-			    hex_string_custom (addr, 8));
+	  /* Now (finally!) create the solib breakpoint.  */
+	  create_solib_event_breakpoint (target_gdbarch (), addr);
 
-      /* Fetch the address of the r_debug struct.  */
-      if (target_read_memory (addr, addr_buf, sizeof addr_buf) != 0)
-	{
-	  warning (_("Unable to fetch contents of _dl_debug_addr "
-		     "(at address %s) from dynamic linker"),
-		   hex_string_custom (addr, 8));
+	  info->enable_break2_done = 1;
+	  ret = 1;
 	}
-      addr = extract_unsigned_integer (addr_buf, sizeof addr_buf, byte_order);
-
-      if (solib_dsbt_debug)
-	fprintf_unfiltered (gdb_stdlog,
-			    "enable_break: _dl_debug_addr[0..3] = %s\n",
-			    hex_string_custom (addr, 8));
-
-      /* If it's zero, then the ldso hasn't initialized yet, and so
-	 there are no shared libs yet loaded.  */
-      if (addr == 0)
+      else
 	{
 	  if (solib_dsbt_debug)
 	    fprintf_unfiltered (gdb_stdlog,
-				"enable_break: ldso not yet initialized\n");
-	  /* Do not warn, but mark to run again.  */
-	  return 0;
+				"enable_break: _dl_debug_state is not found\n");
+	  ret = 0;
 	}
 
-      /* Fetch the r_brk field.  It's 8 bytes from the start of
-	 _dl_debug_addr.  */
-      if (target_read_memory (addr + 8, addr_buf, sizeof addr_buf) != 0)
-	{
-	  warning (_("Unable to fetch _dl_debug_addr->r_brk "
-		     "(at address %s) from dynamic linker"),
-		   hex_string_custom (addr + 8, 8));
-	  enable_break_failure_warning ();
-	  gdb_bfd_unref (tmp_bfd);
-	  return 0;
-	}
-      addr = extract_unsigned_integer (addr_buf, sizeof addr_buf, byte_order);
-
       /* We're done with the temporary bfd.  */
       gdb_bfd_unref (tmp_bfd);
 
       /* We're also done with the loadmap.  */
       xfree (ldm);
 
-      /* Remove all the solib event breakpoints.  Their addresses
-	 may have changed since the last time we ran the program.  */
-      remove_solib_event_breakpoints ();
-
-      /* Now (finally!) create the solib breakpoint.  */
-      create_solib_event_breakpoint (target_gdbarch (), addr);
-
-      info->enable_break2_done = 1;
-
-      return 1;
+      return ret;
     }
 
   /* Tell the user we couldn't set a dynamic linker breakpoint.  */
@@ -979,44 +926,6 @@ enable_break2 (void)
   return 0;
 }
 
-static int
-enable_break (void)
-{
-  asection *interp_sect;
-  struct minimal_symbol *start;
-
-  /* Check for the presence of a .interp section.  If there is no
-     such section, the executable is statically linked.  */
-
-  interp_sect = bfd_get_section_by_name (exec_bfd, ".interp");
-
-  if (interp_sect == NULL)
-    {
-      if (solib_dsbt_debug)
-	fprintf_unfiltered (gdb_stdlog,
-			    "enable_break: No .interp section found.\n");
-      return 0;
-    }
-
-  start = lookup_minimal_symbol ("_start", NULL, symfile_objfile);
-  if (start == NULL)
-    {
-      if (solib_dsbt_debug)
-	fprintf_unfiltered (gdb_stdlog,
-			    "enable_break: symbol _start is not found.\n");
-      return 0;
-    }
-
-  create_solib_event_breakpoint (target_gdbarch (),
-				 SYMBOL_VALUE_ADDRESS (start));
-
-  if (solib_dsbt_debug)
-    fprintf_unfiltered (gdb_stdlog,
-			"enable_break: solib event breakpoint placed at : %s\n",
-			hex_string_custom (SYMBOL_VALUE_ADDRESS (start), 8));
-  return 1;
-}
-
 /* Once the symbols from a shared object have been loaded in the usual
    way, we are called to do any system specific symbol handling that
    is needed.  */
-- 
1.7.7.6


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