[RFC/ia64-linux] pb with shared libraries when attaching to process

Joel Brobecker brobecker@adacore.com
Fri Apr 25 02:06:00 GMT 2008


Hello,

It's something I hadn't noticed before with gdb-6.8 because there
was no visible symptoms on the machine I used to do the testing.
But with another machine, I get the following type of error:

        (gdb) att 31147
        Attaching to program: /taff.a/brobecke/regr/ex/foo, process 31147
        Reading symbols from /lib/tls/libc.so.6.1...done.
        Loaded symbols for /lib/tls/libc.so.6.1
        Reading symbols from /lib/ld-linux-ia64.so.2...done.
        Loaded symbols for /lib/ld-linux-ia64.so.2
        0xa000000000010641 in __kernel_syscall_via_break ()
        (gdb) c
        Continuing.
 !!! -> Can't insert breakpoint for slot numbers greater than 2.

The reason for the error message is that GDB is trying to insert
a shlib breakpoint at an address that is invalid for ia64:

    (gdb) maintenance info break
    Num     Type           Disp Enb Address            What
    -1      shlib events   keep y   0x200000000003b768 <local+168>

(the slot number is encoded in the last 4 bits of the address and
should be either 0, 1, or 2).

With older versions of GDB (we were using gdb-6.6), we used to break
on one of the SOLIB_BREAK_NAMES routines, whichever is found first.
In our case, gdb-6.6 was showing:

    (gdb) maintenance info break
    Num Type           Disp Enb Address            What
    -1  shlib events   keep y   0x200000000001b720 <_dl_debug_state>

I think this is the right location to break, as I wrote a little
C program that does a dlopen, and I could witness the breakpoint
being triggered when I "next" over the dlopen operation (again,
with gdb-6.6):

    (gdb) next
    [...]
    infrun: TARGET_WAITKIND_STOPPED
    infrun: stop_pc = 0x200000000001acd0
    infrun: BPSTAT_WHAT_CHECK_SHLIBS
    [...]

With gdb-6.8, we now first try r_brk, and only if it doesn't work
do we fallback on the previous method.

This address is stored at DEBUG_BASE + lmo->r_brk_offset. For LP64,
the r_brk_offset is set to 16 bytes, so that's DEBUG_BASE + 16.
As far as I can tell, the DEBUG_BASE value that we compute seems
correct - we obtain it from the DT_DEBUG dynamic tag, and the value
matches the address of the "_r_debug" symbol. So it's not obviously
wrong.

Assuming that the DEBUG_BASE is correct, dumping the memory at
this address shows:

 40a28 <_r_debug>:   0x00000001      0x00000000      0x00040a50     0x20000000
 40a38 <_r_debug+16>:0x0003b768      0x20000000      0x00000000     0x00000000
 40a48 <_r_debug+32>:0x00000000      0x20000000      0x00000000     0x00000000
 40a58:              0x000287a0      0x20000000      0x0000d988     0x60000000
 40a68:              0x00041500      0x20000000      0x00000000     0x00000000
 40a78:              0x00040a50      0x20000000      0x00000000     0x00000000
 40a88:              0x00040ea0      0x20000000      0x00000000     0x00000000
 40a98:              0x0000d988      0x60000000      0x0000da78     0x60000000
 40aa8:              0x0000da68      0x60000000      0x0000d9f8     0x60000000
 40ab8:              0x0000da08      0x60000000      0x0000da18     0x60000000

First it confirms why we've determine that r_brk is at 0x200000000003b768.
It also seems to say that the address of _dl_debug_state isnt' saved
in that memory region.

Note that, even in the case when the r_brk address found does not cause
the error, it is still incorrect, as I dont see it being triggered
when stepping over dlopen().

Not knowing how things work underneath, I am a bit stuck. I tried finding
some documentation on how things are supposed to work, to no avail.
What do you guys think? bug in the loader? Problem in the debugger?

Thanks,
-- 
Joel



More information about the Gdb-patches mailing list