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]

Re: ping: [patch 2/6] PIE: Attach binary even after ld.so re-prelinked underneath


On Tue, 29 Jun 2010 20:21:32 +0200, Joel Brobecker wrote:
>     /* The location of the _dl_auxv symbol may no longer be correct if
>        ld.so was prelinked after the program was started, which can cause
>        the memory read at its address to fail.  When that happens, return
>        -1 to fallback on another mechanism for retrieving the AUXV.
> 
>        While this allows things to work in most cases, this still does not
>        work in the case where we are attaching the debugger to a PIE
>        running under valgrind and --db-attach=yes (again, when the on-disk
>        ld.so file was changed due to prelink after the process was started).
>        [WHY???]
>        However, we have not found a solution to that problem yet, and we
>        think that we might need a valgrind extension to make it work.
>        This is PR 11440.  */

I see now my comment did not specify the currently failing set of cases
exactly.  Moreover I was not aware of the PIEs prelinking - they are never
prelinked themselves - it is true it does not make much sense.  Still such
functionality is needed for debugging executed prelinked PIC libraries (such
cas ld.so and libc.so, other libraries usually do not support their execution
and they crash on such attempt).  Still the testsuite should therefore target
more executing prelinked PICs than prelinked PIEs (currently kept unchanged).

Therefore used some merged+modified comment:

  /* The location of the _dl_auxv symbol may no longer be correct if
     ld.so runs at a different address than the one present in the file.
     This is very common case - for unprelinked ld.so or with a PIE executable.
     PIE executable forces random address even for libraries already being
     prelinked to some address.  PIE executables themselves are never prelinked
     even on prelinked systems.  Prelinking of a PIE executable would block
     their purpose of randomizing load of everything including the executable.

     If the memory read fails, return -1 to fallback on another mechanism for
     retrieving the AUXV.

     In most cases of a PIE running under valgrind there is no way how to find
     out the base addresses of any of ld.so, executable or AUXV as everything
     is randomized and /proc information is not relevant for the virtual
     executable running under valgrind.  We think that we might need a valgrind
     extension to make it work.  This is PR 11440.  */


> >  	foreach relink {YES NO} {
> > -	    if {[prelink$relink $relink_args [file tail $exec]]
> > -	        && [copy $interp_saved $interp]} {
> > +	    # It would be more correct to also [copy $interp_saved $interp]
> > +	    # here to really test just different prelink of $exec.
> > +	    # But we would need a separate test for different prelink of ld.so
> > +	    # where a bug occured.  It is now all merged into this single test.
> > +	    if [prelink$relink $relink_args [file tail $exec]] {
> >  		# /proc/PID/exe cannot be loaded as it is "EXECNAME (deleted)".
> >  		test_attach_gdb $exec $pid $displacement "attach-relink$relink"
> 
> As discussed on IRC, let's expand the comment to provide the explanation
> that your provided there.
> 
> Basically: * what we used to do (the copy) and why (restore ld.so to
>              prevent an ld.so prelink)
>            * why we are no longer doing it
>              (making sure that we test GDB with ld.so being prelinked too)

Used:
            # Formerly this test was testing only prelinking of $EXEC.  As the
            # prelink command prelinks automatically even all $EXEC's libraries
            # even $INTERP got prelinked.  Therefore we formerly had to
            # `[copy $interp_saved $interp]' to make $INTERP not affected by
            # this prelinking of $EXEC.
            #
            # But now we need to test even prelinking of $INTERP.  We could
            # create a separate test to test just the $INTERP prelinking.  For
            # the test simplicity we merged this test and the test above by not
            # restoring $INTERP after $EXEC prelink.  $INTERP gets restored 
            # later below.


Thanks,
Jan


gdb/
2010-07-04  Jan Kratochvil  <jan.kratochvil@redhat.com>
	    Joel Brobecker  <brobecker@adacore.com>

	* auxv.c (ld_so_xfer_auxv): Do not error on failed read of data_address.

gdb/testsuite/
2010-07-04  Jan Kratochvil  <jan.kratochvil@redhat.com>
	    Joel Brobecker  <brobecker@adacore.com>

	* gdb.base/break-interp.exp (test_attach): Keep $interp changed.  Move
	its restore after the <$relink_args != ""> loop.  new comment.

--- a/gdb/auxv.c
+++ b/gdb/auxv.c
@@ -96,7 +96,27 @@ ld_so_xfer_auxv (gdb_byte *readbuf,
 
   pointer_address = SYMBOL_VALUE_ADDRESS (msym);
 
-  data_address = read_memory_typed_address (pointer_address, ptr_type);
+  /* The location of the _dl_auxv symbol may no longer be correct if
+     ld.so runs at a different address than the one present in the file.
+     This is very common case - for unprelinked ld.so or with a PIE executable.
+     PIE executable forces random address even for libraries already being
+     prelinked to some address.  PIE executables themselves are never prelinked
+     even on prelinked systems.  Prelinking of a PIE executable would block
+     their purpose of randomizing load of everything including the executable.
+
+     If the memory read fails, return -1 to fallback on another mechanism for
+     retrieving the AUXV.
+
+     In most cases of a PIE running under valgrind there is no way how to find
+     out the base addresses of any of ld.so, executable or AUXV as everything
+     is randomized and /proc information is not relevant for the virtual
+     executable running under valgrind.  We think that we might need a valgrind
+     extension to make it work.  This is PR 11440.  */
+
+  if (target_read_memory (pointer_address, ptr_buf, ptr_size) != 0)
+    return -1;
+
+  data_address = extract_typed_address (ptr_buf, ptr_type);
 
   /* Possibly still not initialized such as during an inferior startup.  */
   if (data_address == 0)
--- a/gdb/testsuite/gdb.base/break-interp.exp
+++ b/gdb/testsuite/gdb.base/break-interp.exp
@@ -425,12 +425,24 @@ proc test_attach {file displacement {relink_args ""}} {
 	global exec interp_saved interp
 
 	foreach relink {YES NO} {
-	    if {[prelink$relink $relink_args [file tail $exec]]
-	        && [copy $interp_saved $interp]} {
+	    # Formerly this test was testing only prelinking of $EXEC.  As the
+	    # prelink command prelinks automatically even all $EXEC's libraries
+	    # even $INTERP got prelinked.  Therefore we formerly had to
+	    # `[copy $interp_saved $interp]' to make $INTERP not affected by
+	    # this prelinking of $EXEC.
+	    #
+	    # But now we need to test even prelinking of $INTERP.  We could
+	    # create a separate test to test just the $INTERP prelinking.  For
+	    # the test simplicity we merged this test and the test above by not
+	    # restoring $INTERP after $EXEC prelink.  $INTERP gets restored
+	    # later below.
+
+	    if [prelink$relink $relink_args [file tail $exec]] {
 		# /proc/PID/exe cannot be loaded as it is "EXECNAME (deleted)".
 		test_attach_gdb $exec $pid $displacement "attach-relink$relink"
 	    }
 	}
+	copy $interp_saved $interp
     }
 
     remote_exec host "kill -9 $pid"


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