[PATCH] Add static probes to runtime linker

Gary Benson gbenson@redhat.com
Mon Jun 25 13:10:00 GMT 2012


Hi all,

This patch adds a number of static probes to the runtime linker,
allowing debuggers to more finely control where they stop and
passing more information so as to allow debugging of programs
that use dlmopen.  A detailed description of the problems I am
attempting to solve (and a patch for the GDB side) is here:

  http://www.cygwin.com/ml/gdb-patches/2012-05/msg00130.html

How does it look?

Cheers,
Gary

-- 
http://gbenson.net/
-------------- next part --------------
2012-06-25  Gary Benson  <gbenson@redhat.com>

	* elf/rtld.c: Include <stap-probe.h>.
	(dl_main): Added static probes "rtld_init_start" and
	"rtld_init_complete".
	* elf/dl-load.c: Include <stap-probe.h>.
	(lose): Take new parameter "nsid".
	Added static probe "rtld_map_complete".
	(_dl_map_object_from_fd): Pass namespace id to lose.
	Added static probe "rtld_map_start".
	(open_verify): Pass namespace id to lose.
	* elf/dl-open.c: Include <stap-probe.h>.
	(dl_open_worker) Added static probes "rtld_map_complete",
	"rtld_reloc_start" and "rtld_reloc_complete".
	* elf/dl-close.c: Include <stap-probe.h>.
	(_dl_close_worker): Added static probes "rtld_unmap_start" and
	"rtld_unmap_complete".

diff --git a/elf/rtld.c b/elf/rtld.c
index a5b0ab9..a99768f 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -39,6 +39,7 @@
 #include <dl-osinfo.h>
 #include <dl-procinfo.h>
 #include <tls.h>
+#include <stap-probe.h>
 #include <stackinfo.h>
 
 #include <assert.h>
@@ -1683,6 +1684,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
   /* We start adding objects.  */
   r->r_state = RT_ADD;
   _dl_debug_state ();
+  LIBC_PROBE (rtld_init_start, 2, LM_ID_BASE, r);
 
   /* Auditing checkpoint: we are ready to signal that the initial map
      is being constructed.  */
@@ -2400,6 +2402,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
   r = _dl_debug_initialize (0, LM_ID_BASE);
   r->r_state = RT_CONSISTENT;
   _dl_debug_state ();
+  LIBC_PROBE (rtld_init_complete, 2, LM_ID_BASE, r);
 
 #ifndef MAP_COPY
   /* We must munmap() the cache file.  */
diff --git a/elf/dl-load.c b/elf/dl-load.c
index fe83f87..69ed3ea 100644
--- a/elf/dl-load.c
+++ b/elf/dl-load.c
@@ -35,6 +35,7 @@
 #include <stackinfo.h>
 #include <caller.h>
 #include <sysdep.h>
+#include <stap-probe.h>
 
 #include <dl-dst.h>
 
@@ -882,7 +883,7 @@ _dl_init_paths (const char *llp)
 static void
 __attribute__ ((noreturn, noinline))
 lose (int code, int fd, const char *name, char *realname, struct link_map *l,
-      const char *msg, struct r_debug *r)
+      const char *msg, struct r_debug *r, Lmid_t nsid)
 {
   /* The file might already be closed.  */
   if (fd != -1)
@@ -896,6 +897,7 @@ lose (int code, int fd, const char *name, char *realname, struct link_map *l,
     {
       r->r_state = RT_CONSISTENT;
       _dl_debug_state ();
+      LIBC_PROBE (rtld_map_complete, 2, nsid, r);
     }
 
   _dl_signal_error (code, name, NULL, msg);
@@ -934,7 +936,7 @@ _dl_map_object_from_fd (const char *name, int fd, struct filebuf *fbp,
       errval = errno;
     call_lose:
       lose (errval, fd, name, realname, l, errstring,
-	    make_consistent ? r : NULL);
+	    make_consistent ? r : NULL, nsid);
     }
 
   /* Look again to see if the real name matched another already loaded.  */
@@ -1041,6 +1043,7 @@ _dl_map_object_from_fd (const char *name, int fd, struct filebuf *fbp,
 	 linking has not been used before.  */
       r->r_state = RT_ADD;
       _dl_debug_state ();
+      LIBC_PROBE (rtld_map_start, 2, nsid, r);
       make_consistent = true;
     }
   else
@@ -1736,7 +1739,7 @@ open_verify (const char *name, struct filebuf *fbp, struct link_map *loader,
 	      name = strdupa (realname);
 	      free (realname);
 	    }
-	  lose (errval, fd, name, NULL, NULL, errstring, NULL);
+	  lose (errval, fd, name, NULL, NULL, errstring, NULL, 0);
 	}
 
       /* See whether the ELF header is what we expect.  */
diff --git a/elf/dl-open.c b/elf/dl-open.c
index 9fe0a7f..de73e26 100644
--- a/elf/dl-open.c
+++ b/elf/dl-open.c
@@ -32,6 +32,7 @@
 #include <caller.h>
 #include <sysdep-cancel.h>
 #include <tls.h>
+#include <stap-probe.h>
 
 #include <dl-dst.h>
 
@@ -291,6 +292,7 @@ dl_open_worker (void *a)
   struct r_debug *r = _dl_debug_initialize (0, args->nsid);
   r->r_state = RT_CONSISTENT;
   _dl_debug_state ();
+  LIBC_PROBE (rtld_map_complete, 2, args->nsid, r);
 
   /* Print scope information.  */
   if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_SCOPES, 0))
@@ -376,10 +378,19 @@ dl_open_worker (void *a)
 	}
     }
 
+  int relocation_in_progress = 0;
+
   for (size_t i = nmaps; i-- > 0; )
     {
       l = maps[i];
 
+      if (! relocation_in_progress)
+	{
+	  /* Notify the debugger that relocations are about to happen.  */
+	  LIBC_PROBE (rtld_reloc_start, 2, args->nsid, r);
+	  relocation_in_progress = 1;
+	}
+
 #ifdef SHARED
       if (__builtin_expect (GLRO(dl_profile) != NULL, 0))
 	{
@@ -544,6 +555,10 @@ cannot load any more object with static TLS"));
 	}
     }
 
+  /* Notify the debugger all new objects have been relocated.  */
+  if (relocation_in_progress)
+    LIBC_PROBE (rtld_reloc_complete, 2, args->nsid, r);
+
   /* Run the initializer functions of new objects.  */
   _dl_init (new, args->argc, args->argv, args->env);
 
diff --git a/elf/dl-close.c b/elf/dl-close.c
index d232294..1042905 100644
--- a/elf/dl-close.c
+++ b/elf/dl-close.c
@@ -31,6 +31,7 @@
 #include <sys/mman.h>
 #include <sysdep-cancel.h>
 #include <tls.h>
+#include <stap-probe.h>
 
 
 /* Type of the constructor functions.  */
@@ -477,6 +478,7 @@ _dl_close_worker (struct link_map *map)
   struct r_debug *r = _dl_debug_initialize (0, nsid);
   r->r_state = RT_DELETE;
   _dl_debug_state ();
+  LIBC_PROBE (rtld_unmap_start, 2, nsid, r);
 
   if (unload_global)
     {
@@ -746,6 +748,7 @@ _dl_close_worker (struct link_map *map)
   /* Notify the debugger those objects are finalized and gone.  */
   r->r_state = RT_CONSISTENT;
   _dl_debug_state ();
+  LIBC_PROBE (rtld_unmap_complete, 2, nsid, r);
 
   /* Recheck if we need to retry, release the lock.  */
  out:


More information about the Libc-alpha mailing list