2016-09-06 5 views
2

Я недавно поставил точку останова, где начальный адрес был:У точки останова есть два адреса?

(gdb) b viewscreen_movieplayerst::create(char, viewscreenst*) 
Breakpoint 1 at 0x804beec 

и второй (обычный адрес) был:

(gdb) run 

    Breakpoint 1, 0xf7b46630 
    in viewscreen_movieplayerst::create(char,viewscreenst*)() 
    from/path/libs/libgraphics.so 

Является ли это потому, что исполняемый файл удаляется? Или выполняется исполняемый исполняемый файл и после его изменения адрес изменяется?

Кроме того, основным является:

(gdb) b main 
Breakpoint 1 at 0x804bdec 

Что выглядит довольно близко к адресу, так что я буду включать его.

Edit:

What does the concept of relocation mean?

So most of the binary is composed of reloc table?

+0

Ваш вопрос не совсем ясен для меня. Если адрес отличается при запуске (вы можете проверить с помощью 'info break'), то да, это, вероятно, переключение времени выполнения. Если на самом деле есть два адреса, это может произойти из-за различных оптимизаций компилятора. –

+0

@Tom Tromey В какой ситуации у него будет 2 адреса? Если нет, вы дали мне фразу «runtime relocation», которую я искал – Jim

+0

Предположительно, функция может иметь несколько адресов из-за разрешения вставки и перегрузки. – kfsone

ответ

4

Возможно, вы видите (PLT) адрес процедуры Linkage Table из общей библиотечной функции на Unix?

Компилятор строит таблицу адресов 'trampoline', которые косвенно ссылаются на зависимости разделяемой библиотеки. Это сложная тема, есть подробная статья here

Вот простой пример.

lib.cpp

#include <iostream> 


int foo() 
{ 
    return 0; 
} 

junk.cpp

#include<iostream> 

int foo(); 
int main(int argc, char* argv[]) 
{ 
    int k = foo(); 
    return 0; 
} 

Вкомпилировать

/tmp$ g++ -fPIC -g -std=c++11 -shared -o libtest_library.so lib.cpp 
/tmp$ g++ -g -std=c++11 -o tramp junk.cpp -L . -l test_library 

GDB трампового

Reading symbols from tramp...done. 
(gdb) p foo 
$1 = (<text from jump slot in .got.plt, no debug info>) 0x4006d6 <foo()@plt+6> 
(gdb) b foo 
Breakpoint 1 at 0x4006d0 
(gdb) d 1 
(gdb) r 
Starting program: /tmp/tramp 
lib: 0x602010 
[Inferior 1 (process 12804) exited normally] 
(gdb) b foo 
Breakpoint 2 at 0x4006d0 (2 locations) 
(gdb) info break 
Num  Type   Disp Enb Address   What 
2  breakpoint  keep y <MULTIPLE>   
2.1       y  0x00000000004006d0 <foo()@plt> 
2.2       y  0x00002aaaaacd0a99 in foo() at lib.cpp:6 

Как видите, символ «foo» имеет два адреса и две точки останова. Один из них - PLT, а другой - расположение символов в общей библиотеке.

Как отмечалось в комментариях, реализация шаблонов и оптимизация компилятора также могут создавать несколько адресов для одного символа или строки источника.

+0

Да, определенно имеет отношение к таблице привязки процедуры. Я понял, что адрес «предварительного исполнения» соответствует адресу в файле objdump -d, который я сделал. Спасибо. – Jim