On Thu, Dec 29, 2005 at 03:13:18AM -0500, Matty wrote:
> 
> 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?

dladdr() and dladdr1() only look at the dynamic symbol table, which only
contains GLOB symbols.  When asked for a static symbol, it will usually
give the nearest global symbol.  Try printing out the symbol names to
see how this works.

> 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)) {

Please file a bug.

Cheers,
- 

-- 
Jonathan Adams, Solaris Kernel Development
_______________________________________________
opensolaris-code mailing list
[email protected]
https://opensolaris.org:444/mailman/listinfo/opensolaris-code

Reply via email to