This is the mail archive of the gdb-patches@sources.redhat.com 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]

[RFA] Enhance GDB to break inside DSO init code


(My many thanks to David Anderson of SGI for explain in great details
how the runtime loader works, and how to get this working in GDB)

We are running on mips-irix native.

Consider a small program using a DSO (shared library) which has
been compiled with the following switch: -Wl,-init,myinit. This
means that the function myinit() is called when the shared library
is loaded, and before the program is executed.

Now, consider the following sequence of GDB commands:

        % gdb hello_sal
        (gdb) start
        (gdb) b myinit
        (gdb) run

We need to start the program first, in order for GDB to read the DSO
symbols. The expected behavior after the run is for GDB to stop in
myinit. But a limitation in the current startup implementation for
mips-irix is such that we end up inserting the breakpoint in myinit
*after* the DSO -init code is executed, hence too late. As a consequence,
The program runs to completion, vis:

        The program being debugged has been started already.
        Start it from the beginning? (y or n) y
        
        Starting program: /[...]/hello_sal 
        [...]
        Program exited normally.
        Current language:  auto; currently asm

For more details, you can refer to:

        http://sources.redhat.com/ml/gdb-patches/2004-07/msg00030.html

The trick, as explained in the message above, is to stop on syssgi()
exit notifications until we can detect that rld has been mapped in
memory by finding the __dbx_link symbol. Then insert a breakpoint
at its address and run until we reach this breakpoint. We then know
that all DSOs have been mapped at this point, and therefore compute
the list of DSOs and load their symbols. At which point we can finally
insert our shared-library breakpoints and let the program run as usual.
With the attached patch, we now stop at the breakpoint, as expected:

        (gdb) run
        The program being debugged has been started already.
        Start it from the beginning? (y or n) y
        
        Starting program: /[...]/hello_sal 
        
        Breakpoint 2, myinit () at /[...]/pack1.adb:29
        29          i := write (1, msg'address, msg'length);

2004-07-23  Joel Brobecker  <brobecker@gnat.com>

        * procfs.c (dbx_link_bpt_addr): New static global variable.
        (dbx_link_shadow_contents): New static global variable.
        (procfs_wait, case <PR_SYSEXIT>): Handle syssgi events.
        (procfs_wait, case <FLTBPT>): Remove the __dbx_link brekapoint
        if we just hit it.
        (procfs_init_inferior): Enable syssgi() syscall trace if appropriate.
        Reset dbx_link_bpt_addr as the address of __dbx_link() may change
        from run to run.
        (procfs_create_inferior): Remove syssgi syscall-exit notifications
        after the inferior has been forked.
        (remove_dbx_link_breakpoint): New function.
        (dbx_link_addr): New function.
        (insert_dbx_link_bpt_in_file): New function.
        (insert_dbx_link_bpt_in_region): New function.
        (insert_dbx_link_breakpoint): New function.
        (proc_trace_syscalls_1): New function, extracted from
        proc_trace_syscalls.
        (proc_trace_syscalls): Replace extract code by call to
        proc_trace_syscalls_1.
        * solib-irix.c (disable_break): Remove stop_pc assertion, as it
        is no longer valid.

Tested on mips-irix, no regression. OK to commit?

Thanks,
-- 
Joel

Attachment: irix-rld.diff
Description: Text document


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