As per the man page extra_info contains absolute pathname. I am not sure in case I understood the man page correctly, but I am not able to get the absolute path name of the file. Here is what I had tried:
Source code:
#define _GNU_SOURCE
#include <dlfcn.h>
#include <link.h>
#include <stdio.h>
int main2(int i)
{
return 2+i;
}
int main(void)
{
Dl_info i={0};
int r;
// struct link_map ei_={0}, *ei=&ei_;
struct link_map *ei=0;
void *ptr = (void*)main2;
r = dladdr1(ptr, &i, (void**)&ei, RTLD_DL_LINKMAP);
if(r)
{
printf("name = %s [%s]\n", i.dli_sname, ei->l_name);
}
return 1;
}
Compiled like this:
gcc -g3 -rdynamic -ldl dlerr.c
Result:
name = main2 []
gdb session:
24 printf("name = %s [%s]\n", i.dli_sname, ei->l_name);
(gdb)
name = main2 []
27 return 1;
(gdb) p i
$1 = {dli_fname = 0x7fffffffe5a7 "/home/user/learn/dlerr/a.out", dli_fbase = 0x400000,
dli_sname = 0x400674 "main2", dli_saddr = 0x4008bd <main2>}
(gdb) p *ei
$2 = {l_addr = 0, l_name = 0x7ffff7ffe6d8 "", l_ld = 0x600e08, l_next = 0x7ffff7ffe6e0,
l_prev = 0x0}
(gdb)
notes: info parameter gives required path currently but in a complex project we often find relative paths getting printed while debugging (not tried this API). So when man page says extra_info gives absolute path, I would like to depend on it. Again *info and *extra_info are not mutually exclusive wrt returning the path names at least as per man page. (gcc version is 4.8.x).
So when man page says extra_info gives absolute path
The man page doesn't say that. It says:
RTLD_DL_LINKMAP
Obtain a pointer to the link map for the matched file. The
extra_info argument points to a pointer to a link_map
structure (i.e., struct link_map **), defined in <link.h> as:
... copy of struct link_map from link.h ...
The man page is correct: you get a pointer to link_map
. The link.h
is also correct, but incomplete.
What's happening is that in the list of link_map
entries, there are special entires for ELF
objects that were not loaded by the linker; namely the main executable and (on non-ancient versions of glibc) the vdso.
Since these entries were loaded by the kernel, the link_map
doesn't contain their full pathname.
info parameter gives required path currently but in a complex project we often find relative paths getting printed
The path to main executable isn't known by the loader, so it can't tell you where that executable is.
Usually you could find that path by treating the first entry in the link_map
list specially: e.g. use readlink(/proc/self/exe)
.
This fails in corner cases: when the /proc
isn't mounted, or when the main executable has been deleted before your code gets to execute, but these conditions are quite rare.