2017-01-12 3 views
0

В соответствии с man-страницей extra_info содержит абсолютный путь. Я не уверен в том, что правильно понял страницу man, но я не могу получить абсолютное имя пути к файлу. Вот то, что я пробовал:Linux dladdr1(): невозможно получить абсолютный путь к сопоставленному файлу

Исходный код:

#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; 
} 

Составитель так:

gcc -g3 -rdynamic -ldl dlerr.c 

Результат:

name = main2 [] 

сеанса GDB:

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) 

примечания: параметр info предоставляет требуемый путь в настоящее время, но в сложном проекте мы часто находим относительные пути, печатаемые во время отладки (не пробовал этот API). Поэтому, когда man-страница говорит, что extra_info дает абсолютный путь, я бы хотел зависеть от него. Снова * info и * extra_info не являются взаимоисключающими, возвращая имена путей, по крайней мере, на странице руководства. (версия gcc - 4.8.x).

ответ

2

Так что, когда человек говорит, что страница extra_info дает абсолютный путь

странице человека не делает сказать, что. Он 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 ... 

Люди страницы правильно: вы получаете указатель на link_map. link.h - также правильный, но неполный.

Что происходит то, что в списке link_map записей, существуют специальные заходы для ELF объектов, которые были не загружены линкера; а именно основной исполняемый файл и (на не древних версиях glibc) vdso.

Поскольку эти записи были загружены ядром, link_map не содержит их полного пути.

информация параметр дает необходимый путь в настоящее время, но в сложном проекте мы часто находим относительные пути получения печатных

Путь к основной исполняемый файл не известен загрузчиком, так что не могу сказать вам, где этот исполняемый файл.

Обычно вы можете найти этот путь, рассматривая первую запись в списке link_map: например. использование readlink(/proc/self/exe).

Это не работает в случаях, когда /proc не установлен или когда основной исполняемый файл был удален до того, как ваш код будет запущен, но эти условия довольно редки.

+0

man-страница говорит «Путь общего объекта, который содержит адрес» для dli_fname и «Абсолютное имя пути, где был найден объект» для l_name.Поскольку я искал абсолютный путь во время компиляции, поскольку -g3-флаг компиляции хранит много информации, и, как упоминалось мной в соответствии с руководством, похоже, что «не являются взаимоисключающими» (но похоже, что они взаимоисключающие), я взял это как абсолютное имя пути компиляции (отличная функция), которую я никогда нигде не видел. –

+0

> man-страница говорит ... Абсолютное имя пути, где был найден объект "для l_name - это * не означает, что этот текст * цитируется * из' link.h'. –

Смежные вопросы