How to detect libraries opened by dlopen from debugger's perspective - Linux

This is a discussion on How to detect libraries opened by dlopen from debugger's perspective - Linux ; I am writing a program to detect ld-2.4.so loading a library on GNU/Linux i386, and it could detect these events correctly, except that this program could detect the library loaded via "dlopen". This program is a little like debugger, a) ...

+ Reply to Thread
Results 1 to 6 of 6

Thread: How to detect libraries opened by dlopen from debugger's perspective

  1. How to detect libraries opened by dlopen from debugger's perspective


    I am writing a program to detect ld-2.4.so loading a library on
    GNU/Linux i386, and it could detect these events correctly, except
    that this program could detect the library loaded via "dlopen".

    This program is a little like debugger,
    a) Fork a child and execute the program I want to check
    b) Set a breakpoint on _dl_debug_state
    c) Wait for the events caused by breakpoint hit, and read the link_map
    by means of ptrace repeatedly, and print them.

    Now I write a simple test case "test-dl" like this,

    #include
    #include
    #include

    int
    main(int argc, char **argv)
    {
    void *handle;
    double (*cosine)(double);
    char *error;

    handle = dlopen ("/lib/libm.so.6", RTLD_LAZY);
    if (!handle) {
    fputs (dlerror(), stderr);
    exit(1);
    }

    cosine = dlsym(handle, "cos");
    if ((error = dlerror()) != NULL) {
    fputs(error, stderr);
    exit(1);
    }

    printf ("%f\n", (*cosine)(2.0));
    dlclose(handle);
    }


    Here is a part of the source code for your reference,
    b.t.w, I implemented breakpoint and access target memory space by
    myself, and do not post them here, otherwise this mail is too long
    to read.


    struct link_map_list
    {
    unsigned int r_version;
    unsigned int r_map;
    }lml;

    struct link_map
    {
    unsigned int l_addr;
    unsigned int l_name;
    unsigned int l_ld;
    unsigned int l_next;
    unsigned int l_prev;
    }lm;

    /* Check _r_debug in ld-2.4.so */
    long r__debug = 0x4b56a4;


    int
    main()
    {

    int status;
    unsigned char orig;
    struct breakpoint b;
    long l;

    child = fork();
    if(child == 0)
    {
    ptrace(PTRACE_TRACEME, 0, NULL, NULL);
    execl("./test-dl", NULL);
    }
    else
    {
    int i = 0;
    char buffer[40];

    wait(NULL);

    /* Set breakpoint on _dl_debug_state in ld-2.4.so. */
    setup_breakpoint (child, 0x004a93c9, &b);
    ptrace(PTRACE_CONT,child, NULL, NULL);
    /* Avoid endless loop if I make some mistakes, so loop 30 times.*/
    while (i < 30)
    {
    /* Wait until child stop. */
    wait(&status);
    if (WIFEXITED(status))
    {
    printf("Exit status:%d\n",WEXITSTATUS(status));
    return 0;
    }

    if (WIFSTOPPED(status))
    {
    printf("STOPPED by %d\n", WSTOPSIG(status));
    hit_breakpoint(child, &b);

    target_read_memory (r__debug, &lml, sizeof(lml));
    printf("version: %d, map = 0x%x\n", lml.r_version, lml.r_map);

    l = lml.r_map;
    while (l)
    {
    target_read_memory (l, &lm, sizeof(lm));
    target_read_memory (lm.l_name, buffer, sizeof(buffer));
    printf("l_addr 0x%x, l_name 0x%x, l_ld 0x%lx, l_next 0x%x, l_prev 0x%x, ",
    lm.l_addr, lm.l_name, lm.l_ld, lm.l_next, lm.l_prev);
    buffer[sizeof(buffer) - 1] = '\0';
    printf ("name = %s\n", buffer);
    l = lm.l_next;
    }
    }
    if (WIFSIGNALED(status))
    {
    printf("SIGNALED by %d", WTERMSIG(status));
    }

    ptrace(PTRACE_CONT,child, NULL, NULL);

    i++;
    }
    }
    return 0;
    }


    My problem here is, why this program could not detect loading library
    opened by "dlopen"? What is the difference between library and library
    loaded by "dlopen" in link map list in glibc? Thanks in advance!

    --
    Yao Qi
    GNU/Linux Developer

    P.S. Here is the output,
    [22:42][qiyao@GreenOnly:~/SourceCode/ptrace]$ ./ptrace-loader-break
    errno = 0
    STOPPED by 5
    version: 1, map = 0x4b56b8
    l_addr 0x0, l_name 0x4b147b, l_ld 0x80496e0, l_next 0x4b5300, l_prev 0x0, name =
    l_addr 0x0, l_name 0x8048114, l_ld 0x4b4f18, l_next 0x4b5988, l_prev 0x4b56b8, name = /lib/ld-linux.so.2
    l_addr 0x877000, l_name 0x4b147b, l_ld 0x877590, l_next 0x0, l_prev 0x4b5300, name =
    STOPPED by 5
    version: 1, map = 0x4b56b8
    l_addr 0x0, l_name 0x4b147b, l_ld 0x80496e0, l_next 0x4b5988, l_prev 0x0, name =
    l_addr 0x877000, l_name 0x4b147b, l_ld 0x877590, l_next 0xb7fdb3d0, l_prev 0x4b56b8, name =
    l_addr 0x0, l_name 0xb7fdb3c0, l_ld 0x616ed8, l_next 0xb7fdb648, l_prev 0x4b5988, name = /lib/libdl.so.2
    l_addr 0x0, l_name 0xb7fdb638, l_ld 0x5e6d9c, l_next 0x4b5300, l_prev 0xb7fdb3d0, name = /lib/libc.so.6
    l_addr 0x0, l_name 0x8048114, l_ld 0x4b4f18, l_next 0x0, l_prev 0xb7fdb648, name = /lib/ld-linux.so.2
    STOPPED by 5
    version: 1, map = 0x4b56b8
    l_addr 0x0, l_name 0x4b147b, l_ld 0x80496e0, l_next 0x4b5988, l_prev 0x0, name =
    l_addr 0x877000, l_name 0x4b147b, l_ld 0x877590, l_next 0xb7fdb3d0, l_prev 0x4b56b8, name =
    l_addr 0x0, l_name 0xb7fdb3c0, l_ld 0x616ed8, l_next 0xb7fdb648, l_prev 0x4b5988, name = /lib/libdl.so.2
    l_addr 0x0, l_name 0xb7fdb638, l_ld 0x5e6d9c, l_next 0x4b5300, l_prev 0xb7fdb3d0, name = /lib/libc.so.6
    l_addr 0x0, l_name 0x8048114, l_ld 0x4b4f18, l_next 0x0, l_prev 0xb7fdb648, name = /lib/ld-linux.so.2
    STOPPED by 5
    version: 1, map = 0x4b56b8
    l_addr 0x0, l_name 0x4b147b, l_ld 0x80496e0, l_next 0x4b5988, l_prev 0x0, name =
    l_addr 0x877000, l_name 0x4b147b, l_ld 0x877590, l_next 0xb7fdb3d0, l_prev 0x4b56b8, name =
    l_addr 0x0, l_name 0xb7fdb3c0, l_ld 0x616ed8, l_next 0xb7fdb648, l_prev 0x4b5988, name = /lib/libdl.so.2
    l_addr 0x0, l_name 0xb7fdb638, l_ld 0x5e6d9c, l_next 0x4b5300, l_prev 0xb7fdb3d0, name = /lib/libc.so.6
    l_addr 0x0, l_name 0x8048114, l_ld 0x4b4f18, l_next 0x836f020, l_prev 0xb7fdb648, name = /lib/ld-linux.so.2
    l_addr 0x0, l_name 0x836f008, l_ld 0x610ef8, l_next 0x0, l_prev 0x4b5300, name = /lib/libm.so.6
    -0.416147
    STOPPED by 5
    version: 1, map = 0x4b56b8
    l_addr 0x0, l_name 0x4b147b, l_ld 0x80496e0, l_next 0x4b5988, l_prev 0x0, name =
    l_addr 0x877000, l_name 0x4b147b, l_ld 0x877590, l_next 0xb7fdb3d0, l_prev 0x4b56b8, name =
    l_addr 0x0, l_name 0xb7fdb3c0, l_ld 0x616ed8, l_next 0xb7fdb648, l_prev 0x4b5988, name = /lib/libdl.so.2
    l_addr 0x0, l_name 0xb7fdb638, l_ld 0x5e6d9c, l_next 0x4b5300, l_prev 0xb7fdb3d0, name = /lib/libc.so.6
    l_addr 0x0, l_name 0x8048114, l_ld 0x4b4f18, l_next 0x836f020, l_prev 0xb7fdb648, name = /lib/ld-linux.so.2
    l_addr 0x0, l_name 0x836f008, l_ld 0x610ef8, l_next 0x0, l_prev 0x4b5300, name = /lib/libm.so.6
    STOPPED by 5
    version: 1, map = 0x4b56b8
    l_addr 0x0, l_name 0x4b147b, l_ld 0x80496e0, l_next 0x4b5988, l_prev 0x0, name =
    l_addr 0x877000, l_name 0x4b147b, l_ld 0x877590, l_next 0xb7fdb3d0, l_prev 0x4b56b8, name =
    l_addr 0x0, l_name 0xb7fdb3c0, l_ld 0x616ed8, l_next 0xb7fdb648, l_prev 0x4b5988, name = /lib/libdl.so.2
    l_addr 0x0, l_name 0xb7fdb638, l_ld 0x5e6d9c, l_next 0x4b5300, l_prev 0xb7fdb3d0, name = /lib/libc.so.6
    l_addr 0x0, l_name 0x8048114, l_ld 0x4b4f18, l_next 0x0, l_prev 0xb7fdb648, name = /lib/ld-linux.so.2
    Exit status:0

  2. Re: How to detect libraries opened by dlopen from debugger'sperspective

    Yao Qi writes:

    > I am writing a program to detect ld-2.4.so loading a library on
    > GNU/Linux i386, and it could detect these events correctly, except
    > that this program could detect the library loaded via "dlopen".


    s/could detect/could not detect/

    > My problem here is, why this program could not detect loading library
    > opened by "dlopen"?


    Actually, from your output, your program detects dlopen()ed libm
    just fine:

    > STOPPED by 5

    ....
    > l_addr 0x0, l_name 0x836f008, l_ld 0x610ef8, l_next 0x0, l_prev 0x4b5300, name = /lib/libm.so.6


    > What is the difference between library and library
    > loaded by "dlopen" in link map list in glibc?


    Huh?

    I think your real question might be "how come there are 3 images
    already loaded when my first breakpoint fires (and what are the 2
    un-named ones)", but it's not at all clear, and also contradicts
    the subject of your message.

    Perhaps ask your question again, but proof-read it for obvious
    mistakes and clarity?

    Cheers,
    --
    In order to understand recursion you must first understand recursion.
    Remove /-nsp/ for email.

  3. Re: How to detect libraries opened by dlopen from debugger's perspective

    Paul Pluzhnikov writes:

    > Yao Qi writes:
    >
    >> I am writing a program to detect ld-2.4.so loading a library on
    >> GNU/Linux i386, and it could detect these events correctly, except
    >> that this program could detect the library loaded via "dlopen".

    >
    > s/could detect/could not detect/

    Oh, it is a typo. Sorry for this.

    >
    >> My problem here is, why this program could not detect loading library
    >> opened by "dlopen"?

    >
    > Actually, from your output, your program detects dlopen()ed libm
    > just fine:
    >
    >> STOPPED by 5

    > ...
    >> l_addr 0x0, l_name 0x836f008, l_ld 0x610ef8, l_next 0x0, l_prev

    > 0x4b5300, name = /lib/libm.so.6


    To be honest, I red the output for at least three times, but I did not
    find this in the output.

    >
    >> What is the difference between library and library
    >> loaded by "dlopen" in link map list in glibc?

    >

    According the output, the program could detect dlopen()ed libm, and my
    first question was answered.

    > Huh?
    >
    > I think your real question might be "how come there are 3 images
    > already loaded when my first breakpoint fires (and what are the 2
    > un-named ones)", but it's not at all clear, and also contradicts
    > the subject of your message.


    My second question is the same as you said here.

    I run my program again, and ask my questions in the comment of the
    output via [.....]


    $ ./ptrace-loader-break
    errno = 0
    STOPPED by 5
    version: 1, map = 0x4b56b8
    l_addr 0x0, l_name 0x4b147b, l_ld 0x80496e0, l_next 0x4b5300, l_prev 0x0, name =

    [name is NULL since this is the head of link_map list, right?]

    l_addr 0x0, l_name 0x8048114, l_ld 0x4b4f18, l_next 0x4b5988, l_prev 0x4b56b8, name = /lib/ld-linux.so.2
    l_addr 0x9c3000, l_name 0x4b147b, l_ld 0x9c3590, l_next 0x0, l_prev 0x4b5300, name =

    [What is this record? Why l_addr in the record is 0x9c3000, while
    l_addr is 0x0 in other records?]

    STOPPED by 5
    version: 1, map = 0x4b56b8
    l_addr 0x0, l_name 0x4b147b, l_ld 0x80496e0, l_next 0x4b5988, l_prev 0x0, name =
    l_addr 0x9c3000, l_name 0x4b147b, l_ld 0x9c3590, l_next 0xb7faf3d0, l_prev 0x4b56b8, name =

    [Why the name is always NULL?]

    l_addr 0x0, l_name 0xb7faf3c0, l_ld 0x616ed8, l_next 0xb7faf648, l_prev 0x4b5988, name = /lib/libdl.so.2
    l_addr 0x0, l_name 0xb7faf638, l_ld 0x5e6d9c, l_next 0x4b5300, l_prev 0xb7faf3d0, name = /lib/libc.so.6
    l_addr 0x0, l_name 0x8048114, l_ld 0x4b4f18, l_next 0x0, l_prev 0xb7faf648, name = /lib/ld-linux.so.2
    STOPPED by 5
    version: 1, map = 0x4b56b8
    l_addr 0x0, l_name 0x4b147b, l_ld 0x80496e0, l_next 0x4b5988, l_prev 0x0, name =
    l_addr 0x9c3000, l_name 0x4b147b, l_ld 0x9c3590, l_next 0xb7faf3d0, l_prev 0x4b56b8, name =
    l_addr 0x0, l_name 0xb7faf3c0, l_ld 0x616ed8, l_next 0xb7faf648, l_prev 0x4b5988, name = /lib/libdl.so.2
    l_addr 0x0, l_name 0xb7faf638, l_ld 0x5e6d9c, l_next 0x4b5300, l_prev 0xb7faf3d0, name = /lib/libc.so.6
    l_addr 0x0, l_name 0x8048114, l_ld 0x4b4f18, l_next 0x0, l_prev 0xb7faf648, name = /lib/ld-linux.so.2
    STOPPED by 5
    version: 1, map = 0x4b56b8
    l_addr 0x0, l_name 0x4b147b, l_ld 0x80496e0, l_next 0x4b5988, l_prev 0x0, name =
    l_addr 0x9c3000, l_name 0x4b147b, l_ld 0x9c3590, l_next 0xb7faf3d0, l_prev 0x4b56b8, name =
    l_addr 0x0, l_name 0xb7faf3c0, l_ld 0x616ed8, l_next 0xb7faf648, l_prev 0x4b5988, name = /lib/libdl.so.2
    l_addr 0x0, l_name 0xb7faf638, l_ld 0x5e6d9c, l_next 0x4b5300, l_prev 0xb7faf3d0, name = /lib/libc.so.6
    l_addr 0x0, l_name 0x8048114, l_ld 0x4b4f18, l_next 0x829b020, l_prev 0xb7faf648, name = /lib/ld-linux.so.2
    l_addr 0x0, l_name 0x829b008, l_ld 0x610ef8, l_next 0x0, l_prev 0x4b5300, name = /lib/libm.so.6
    -0.416147
    STOPPED by 5
    version: 1, map = 0x4b56b8
    l_addr 0x0, l_name 0x4b147b, l_ld 0x80496e0, l_next 0x4b5988, l_prev 0x0, name =
    l_addr 0x9c3000, l_name 0x4b147b, l_ld 0x9c3590, l_next 0xb7faf3d0, l_prev 0x4b56b8, name =
    l_addr 0x0, l_name 0xb7faf3c0, l_ld 0x616ed8, l_next 0xb7faf648, l_prev 0x4b5988, name = /lib/libdl.so.2
    l_addr 0x0, l_name 0xb7faf638, l_ld 0x5e6d9c, l_next 0x4b5300, l_prev 0xb7faf3d0, name = /lib/libc.so.6
    l_addr 0x0, l_name 0x8048114, l_ld 0x4b4f18, l_next 0x829b020, l_prev 0xb7faf648, name = /lib/ld-linux.so.2
    l_addr 0x0, l_name 0x829b008, l_ld 0x610ef8, l_next 0x0, l_prev 0x4b5300, name = /lib/libm.so.6
    STOPPED by 5
    version: 1, map = 0x4b56b8
    l_addr 0x0, l_name 0x4b147b, l_ld 0x80496e0, l_next 0x4b5988, l_prev 0x0, name =
    l_addr 0x9c3000, l_name 0x4b147b, l_ld 0x9c3590, l_next 0xb7faf3d0, l_prev 0x4b56b8, name =
    l_addr 0x0, l_name 0xb7faf3c0, l_ld 0x616ed8, l_next 0xb7faf648, l_prev 0x4b5988, name = /lib/libdl.so.2
    l_addr 0x0, l_name 0xb7faf638, l_ld 0x5e6d9c, l_next 0x4b5300, l_prev 0xb7faf3d0, name = /lib/libc.so.6
    l_addr 0x0, l_name 0x8048114, l_ld 0x4b4f18, l_next 0x0, l_prev 0xb7faf648, name = /lib/ld-linux.so.2
    Exit status:0



    >
    > Perhaps ask your question again, but proof-read it for obvious
    > mistakes and clarity?
    >
    > Cheers,


    Thanks again for your nice help.

    --
    Yao Qi
    GNU/Linux Developer

  4. Re: How to detect libraries opened by dlopen from debugger'sperspective

    Yao Qi writes:

    >>> My problem here is, why this program could not detect loading library
    >>> opened by "dlopen"?

    >>
    >> Actually, from your output, your program detects dlopen()ed libm
    >> just fine:
    >>

    > To be honest, I red the output for at least three times, but I did not
    > find this in the output.


    What I do is run the program inside emacs, then search for the
    string ... If emacs can't find it, I am pretty sure the string
    really isn't there :-)

    > $ ./ptrace-loader-break
    > errno = 0
    > STOPPED by 5
    > version: 1, map = 0x4b56b8
    > l_addr 0x0, l_name 0x4b147b, l_ld 0x80496e0, l_next 0x4b5300, l_prev 0x0, name =
    >
    > [name is NULL since this is the head of link_map list, right?]


    First off, the name is not NULL, it is 0x4b147b.
    It simply points to an empty string.

    Second, this has nothing to do with it being at the head of the list.
    This entry is for the main executable. I am not sure why the loader
    (ld-linux.so.2) doesn't fill that name; probably because at the
    time this entry is constructed, the name of the exe is not readily
    available.

    Solaris loader does put correct exe name into the link map.

    > l_addr 0x0, l_name 0x8048114, l_ld 0x4b4f18, l_next 0x4b5988, l_prev 0x4b56b8, name = /lib/ld-linux.so.2
    > l_addr 0x9c3000, l_name 0x4b147b, l_ld 0x9c3590, l_next 0x0, l_prev 0x4b5300, name =
    >
    > [What is this record?


    This is the entry for vDSO. You can read about vDSO here:
    http://www.trilithium.com/johan/2005/08/linux-gate/

    > Why l_addr in the record is 0x9c3000,


    Because that's where it happens to be located in memory.

    > while l_addr is 0x0 in other records?]


    A better question might be: "why l_addr is 0 for (some) shared
    libraries?"
    On Solaris, a program iterating over link_map prints:

    l_addr = 0x00010000 "./a.out"
    l_addr = 0xff3a0000 "/lib/libdl.so.1"
    l_addr = 0xff280000 "/lib/libc.so.1"
    l_addr = 0xff388000 "/platform/SUNW,UltraAX-i2/lib/libc_psr.so.1"

    And the comment for l_addr in /usr/include/sys/link.h says:

    unsigned long l_addr; /* address at which object is mapped */

    Clearly /lib/ld-linux.so.2 and /lib/libc.so.6 were not *both*
    loaded at address 0 (in your case).

    The answer is "prelinked DSOs". On recent Linux distributions,
    l_addr no longer shows the "base address" of DSO. Rather, it's offset
    between where the DSO was prelinked and where it was loaded. Read
    more about prelinking here:

    man prelink
    http://people.redhat.com/drepper/lt2002talk.pdf

    > STOPPED by 5
    > version: 1, map = 0x4b56b8
    > l_addr 0x0, l_name 0x4b147b, l_ld 0x80496e0, l_next 0x4b5988, l_prev 0x0, name =
    > l_addr 0x9c3000, l_name 0x4b147b, l_ld 0x9c3590, l_next 0xb7faf3d0, l_prev 0x4b56b8, name =
    >
    > [Why the name is always NULL?]


    On each subsequent load you print the whole link map (i.e. these
    are the same entries that we already discussed above).
    The name continues to point to the empty string.

    Cheers,
    --
    In order to understand recursion you must first understand recursion.
    Remove /-nsp/ for email.

  5. Re: How to detect libraries opened by dlopen from debugger's perspective

    Paul Pluzhnikov writes:

    > Yao Qi writes:
    >
    >>>> My problem here is, why this program could not detect loading

    > library
    >>>> opened by "dlopen"?
    >>>
    >>> Actually, from your output, your program detects dlopen()ed libm
    >>> just fine:
    >>>

    >> To be honest, I red the output for at least three times, but I did not
    >> find this in the output.

    >
    > What I do is run the program inside emacs, then search for the
    > string ... If emacs can't find it, I am pretty sure the string
    > really isn't there :-)


    Hi, Paul,
    I do not think I posted all the source here, and how do you run it? :-)

    >
    >> $ ./ptrace-loader-break
    >> errno = 0
    >> STOPPED by 5
    >> version: 1, map = 0x4b56b8
    >> l_addr 0x0, l_name 0x4b147b, l_ld 0x80496e0, l_next 0x4b5300, l_prev

    > 0x0, name =
    >>
    >> [name is NULL since this is the head of link_map list, right?]

    >
    > First off, the name is not NULL, it is 0x4b147b.
    > It simply points to an empty string.


    Oh, sorry!
    Yes, it points to an empty string, instead of a NULL pointer.

    >
    > Second, this has nothing to do with it being at the head of the list.
    > This entry is for the main executable. I am not sure why the loader
    > (ld-linux.so.2) doesn't fill that name; probably because at the
    > time this entry is constructed, the name of the exe is not readily
    > available.


    I find some comments in gdb/gdb/solib-svr4.c,

    /* For SVR4 versions, the first entry in the link map is for the
    inferior executable, so we must ignore it. For some versions of
    SVR4, it has no name. For others (Solaris 2.3 for example), it
    does have a name, so we can no longer use a missing name to
    decide when to ignore it. */
    if (IGNORE_FIRST_LINK_MAP_ENTRY (new) && ldsomap == 0)
    free_so (new);
    else
    {

    I do not know this is the answer to my question or not. At least, we
    could know the first record has no name on GNU/Linux.

    >
    > Solaris loader does put correct exe name into the link map.


    You are right, according to this comments above

    >
    >> l_addr 0x0, l_name 0x8048114, l_ld 0x4b4f18, l_next 0x4b5988, l_prev

    > 0x4b56b8, name = /lib/ld-linux.so.2
    >> l_addr 0x9c3000, l_name 0x4b147b, l_ld 0x9c3590, l_next 0x0, l_prev

    > 0x4b5300, name =
    >>
    >> [What is this record?

    >
    > This is the entry for vDSO. You can read about vDSO here:
    > http://www.trilithium.com/johan/2005/08/linux-gate/
    >


    I heard of vDSO before, and this article is great. I read it for three
    times, but still could not understand it fully.
    How do know this the entry for vDSO? There is no special marks or id to
    tell you it is an entry for vDSO, from my perspective. 0x9c3000 is not
    an evidence that this entry is vDSO, since vDSO is *not* loaded at a
    fixed address.(correct me, if I am wrong)

    >> Why l_addr in the record is 0x9c3000,

    >
    > Because that's where it happens to be located in memory.
    >
    >> while l_addr is 0x0 in other records?]

    >
    > A better question might be: "why l_addr is 0 for (some) shared
    > libraries?"
    > On Solaris, a program iterating over link_map prints:
    >
    > l_addr = 0x00010000 "./a.out"
    > l_addr = 0xff3a0000 "/lib/libdl.so.1"
    > l_addr = 0xff280000 "/lib/libc.so.1"
    > l_addr = 0xff388000 "/platform/SUNW,UltraAX-i2/lib/libc_psr.so.1"
    >
    > And the comment for l_addr in /usr/include/sys/link.h says:
    >
    > unsigned long l_addr; /* address at which object is mapped */
    >
    > Clearly /lib/ld-linux.so.2 and /lib/libc.so.6 were not *both*
    > loaded at address 0 (in your case).


    Do you mean /lib/ld-linux.so.2 and /lib/libc.so.6 were not *both* loaded
    at address 0, if my case is run on Solaris ?

    The output from my program(on Linux) is,

    l_addr 0x0, l_name 0x4b147b, l_ld 0x80496e0, l_next 0x4b5988, l_prev 0x0, name =
    l_addr 0xecd000, l_name 0x4b147b, l_ld 0xecd590, l_next 0xb7f693d0, l_prev 0x4b56b8, name =
    l_addr 0x0, l_name 0xb7f693c0, l_ld 0x616ed8, l_next 0xb7f69648, l_prev 0x4b5988, name = /lib/libdl.so.2
    l_addr 0x0, l_name 0xb7f69638, l_ld 0x5e6d9c, l_next 0x4b5300, l_prev 0xb7f693d0, name = /lib/libc.so.6
    l_addr 0x0, l_name 0x8048114, l_ld 0x4b4f18, l_next 0x9ae1020, l_prev 0xb7f69648, name = /lib/ld-linux.so.2
    l_addr 0x0, l_name 0x9ae1008, l_ld 0x610ef8, l_next 0x0, l_prev 0x4b5300, name = /lib/libm.so.6



    >
    > The answer is "prelinked DSOs". On recent Linux distributions,
    > l_addr no longer shows the "base address" of DSO. Rather, it's offset
    > between where the DSO was prelinked and where it was loaded. Read
    > more about prelinking here:
    >
    > man prelink
    > http://people.redhat.com/drepper/lt2002talk.pdf


    Emm, it is the first time I hear "prelink", and this doc looks great.
    Thanks for this information.

    b.t.w, I have read some doc written by Ulrich Drepper, but missed this
    one. :-)

    --
    Yao Qi
    GNU/Linux Developer

  6. Re: How to detect libraries opened by dlopen from debugger'sperspective

    Yao Qi writes:

    > Paul Pluzhnikov writes:


    >> What I do is run the program inside emacs, then search for the
    >> string ... If emacs can't find it, I am pretty sure the string
    >> really isn't there :-)

    >
    > I do not think I posted all the source here, and how do you run it? :-)


    I didn't run your program. This was just a general comment on how
    to avoid this particular error.

    >> This is the entry for vDSO...
    >>

    > How do know this the entry for vDSO?


    Because it's the only one besides main exe (which is always first)
    that doesn't have a name.

    >> Clearly /lib/ld-linux.so.2 and /lib/libc.so.6 were not *both*
    >> loaded at address 0 (in your case).

    >
    > Do you mean /lib/ld-linux.so.2 and /lib/libc.so.6 were not *both* loaded
    > at address 0, if my case is run on Solaris ?


    No. I mean that they can't possibly be loaded at the same address
    on Linux. Nor could they be loaded at address 0, which is kept
    inaccessible to detect and prevent NULL pointer dereferences.

    Cheers,
    --
    In order to understand recursion you must first understand recursion.
    Remove /-nsp/ for email.

+ Reply to Thread