Howdy,

Could someone on the list with access to the complete dladdr1() source code take a look to see how the value of info is set? When I compile and run the following code:

$ cat dladdr.c
#include <stdio.h>
#include <dlfcn.h>
#include <sys/elf.h>

static void static_func() { }

void global_func() { }

int main(int argc, char *argv[]) {
    Dl_info dlip;
    Elf32_Sym *info;

    if (dladdr1(global_func, &dlip, (void **)&info, RTLD_DL_SYMENT))
        printf("Global: info points to symbol table entry at 0x%0x\n"
               "        st_value = %d, st_size = %d\n", info,
                        info->st_value, info->st_size);

    if (dladdr1(static_func, &dlip, (void **)&info, RTLD_DL_SYMENT))
        printf("Static: info points to symbol table entry at 0x%0x\n"
               "        st_value = %d, st_size = %d\n", info,
                        info->st_value, info->st_size);

    return(0);
}

I am having trouble correlating the values from dladdr1() with the values provided by nm ( for the static function only ):

$ ./dladdr
Global: info points to symbol table entry at 0x1027c
        st_value = 67264, st_size = 12
Static: info points to symbol table entry at 0x102ec
        st_value = 66800, st_size = 116

$ nm dladdr | grep func
[84]    |     67264|      12|FUNC |GLOB |0    |9      |global_func
[58]    |     67252|      12|FUNC |LOCL |0    |9      |static_func

Does anyone happen to have any insight into why this may be occuring?

Secondly, in display_stack_info(), which is called from printstack() in libc, no attempt is made to verify that sym is not a NULL pointer
prior to deferencing it:

482     if (dladdr1((void *) pc, &info, (void**) &sym,
            RTLD_DL_SYMENT) == 0) {
483             /* no info at all */
484             if (signo == 0)
485                     async_filenoprintf(filenum, "0x%x\n", pc);
486             else
487                     async_filenoprintf(filenum,
488                         "0x%x [ Signal %d (%s)]\n", pc,
489                         (ulong_t)signo, sigbuf);
490
491     } else if ((pc - (unsigned long)info.dli_saddr) <
492         sym->st_size) {

This caused my segfault handler to SEGFAULT (cute isn't it), and I would like to recommend adding a check similar to the following:

491     } else if (sym && ((pc - (unsigned long)info.dli_saddr) <
492                           sym->st_size)) {

Thanks,
- Ryan
--
UNIX Administrator
http://daemons.net/~matty
_______________________________________________
opensolaris-code mailing list
[email protected]
https://opensolaris.org:444/mailman/listinfo/opensolaris-code

Reply via email to