2015-02-11 69 views
2

我可以调试某些程序(比如/斌/ LS)是这样的:如何使用自定义elf解释器来调试程序?

[[email protected] ~]$ gdb -q --args /bin/ls 
Reading symbols from /bin/ls...Reading symbols from /bin/ls...(no debugging symbols found)...done. 
(no debugging symbols found)...done. 
Missing separate debuginfos, use: debuginfo-install coreutils-8.22-19.fc21.x86_64 
(gdb) start 
Temporary breakpoint 1 at 0x402990 
Starting program: /usr/bin/ls 
[Thread debugging using libthread_db enabled] 
Using host libthread_db library "/lib64/libthread_db.so.1". 

Temporary breakpoint 1, 0x0000000000402990 in main() 
(gdb) 

在这里,我可以在main设置临时断点,在它停止。

但我不得不使用定制的小精灵的解释是这样运行程序:

[[email protected] ~]$ gdb -q --args /lib64/ld-linux-x86-64.so.2 /bin/ls 
Reading symbols from /lib64/ld-linux-x86-64.so.2...Reading symbols from /usr/lib/debug/usr/lib64/ld-2.20.so.debug...done. 
done. 
(gdb) start 
Function "main" not defined. 
Make breakpoint pending on future shared library load? (y or [n]) y 
Temporary breakpoint 1 (main) pending. 
Starting program: /usr/lib64/ld-linux-x86-64.so.2 /bin/ls 
[Thread debugging using libthread_db enabled] 
Using host libthread_db library "/lib64/libthread_db.so.1". 
1234   glibc-2.20  python  tmp 
[Inferior 1 (process 2610) exited normally] 
Missing separate debuginfos, use: debuginfo-install libacl-2.2.52-7.fc21.x86_64 libattr-2.4.47-9.fc21.x86_64 libcap-2.24-7.fc21.x86_64 pcre-8.35-8.fc21.x86_64 
(gdb) 

这里GDB没有在main停止,因为符号/未加载斌/ LS。 在这种情况下,我如何强制gdb加载符号并在main处停止?

回答

7

这里是你如何能做到这:

cat t.c 
#include <stdio.h> 
#include <stdlib.h> 

int main() 
{ 
    printf("Hello\n"); 
    return 0; 
} 

gcc -g t.c 
gdb -q --args /usr/lib64/ld-linux-x86-64.so.2 ./a.out 
(gdb) start 
Function "main" not defined. 
Starting program: /usr/lib64/ld-linux-x86-64.so.2 ./a.out 
Hello 
[Inferior 1 (process 7134) exited normally] 

到目前为止,一切都匹配你观察到的东西。现在的解决方案:

(gdb) set stop-on-solib-events 1 
(gdb) r 
Starting program: /usr/lib64/ld-linux-x86-64.so.2 ./a.out 
Stopped due to shared library event (no libraries added or removed) 
(gdb) c 
Continuing. 
Stopped due to shared library event: 
    Inferior loaded /usr/lib64/ld-linux-x86-64.so.2 
(gdb) c 
Continuing. 
Stopped due to shared library event: 
    Inferior loaded /usr/lib64/libc.so.6 

在这一点上,./a.out也被加载,并且可以确认有:

(gdb) info proc map 
process 7140 
Mapped address spaces: 

      Start Addr   End Addr  Size  Offset objfile 
      0x400000   0x401000  0x1000  0x0 /tmp/a.out 
      0x600000   0x601000  0x1000  0x0 /tmp/a.out 
      0x601000   0x602000  0x1000  0x1000 /tmp/a.out 
     0x555555554000  0x555555579000 0x25000  0x0 /usr/lib64/ld-2.19.so 
     0x555555779000  0x55555577a000  0x1000 0x25000 /usr/lib64/ld-2.19.so 
     0x55555577a000  0x55555577c000  0x2000 0x26000 /usr/lib64/ld-2.19.so 
     0x7ffff7c2a000  0x7ffff7c2d000  0x3000  0x0 
     0x7ffff7c2d000  0x7ffff7df0000 0x1c3000  0x0 /usr/lib64/libc-2.19.so 
     0x7ffff7df0000  0x7ffff7fef000 0x1ff000 0x1c3000 /usr/lib64/libc-2.19.so 
     0x7ffff7fef000  0x7ffff7ff3000  0x4000 0x1c2000 /usr/lib64/libc-2.19.so 
     0x7ffff7ff3000  0x7ffff7ff5000  0x2000 0x1c6000 /usr/lib64/libc-2.19.so 
     0x7ffff7ff5000  0x7ffff7ff9000  0x4000  0x0 
     0x7ffff7ff9000  0x7ffff7ffa000  0x1000  0x0 /etc/ld.so.cache 
     0x7ffff7ffa000  0x7ffff7ffd000  0x3000  0x0 
     0x7ffff7ffd000  0x7ffff7fff000  0x2000  0x0 [vdso] 
     0x7ffffffde000  0x7ffffffff000 0x21000  0x0 [stack] 
    0xffffffffff600000 0xffffffffff601000  0x1000  0x0 [vsyscall] 

不幸的是,GDB不明白,它也应该载入符号./a.out 。你必须告诉它:

(gdb) add-symbol-file ./a.out 
The address where ./a.out has been loaded is missing 

有人会认为,这需要GDB的地址是从上面info proc map0x400000。一个会是错的。 GDB需要的实际地址为.text部分,你可以从readelf得到的开始:

readelf -WS ./a.out | grep text 
    [13] .text    PROGBITS  0000000000400440 000440 000182 00 AX 0 0 16 

返回GDB:

(gdb) add-symbol-file ./a.out 0x0000000000400440 
add symbol table from file "./a.out" at 
    .text_addr = 0x400440 
Reading symbols from ./a.out...done. 

现在我们可以在main突破:

(gdb) b main 
Breakpoint 1 at 0x400531: file t.c, line 6. 
(gdb) c 
Continuing. 

Breakpoint 1, main() at t.c:6 
6  printf("Hello\n"); 
(gdb) n 
Hello 
7  return 0; 

Voila!

P.S.重新运行二进制可能会给你一些小问题:

(gdb) r 
Starting program: /usr/lib64/ld-linux-x86-64.so.2 ./a.out 
Error in re-setting breakpoint 1: Cannot access memory at address 0x40052d 
Error in re-setting breakpoint 1: Cannot access memory at address 0x40052d 
Stopped due to shared library event (no libraries added or removed) 

发生这种情况,因为ld-linux尚未映射./a.out。但可以继续:

(gdb) c 
Continuing. 
Stopped due to shared library event: 
    Inferior loaded /usr/lib64/ld-linux-x86-64.so.2 
(gdb) c 
Continuing. 
Stopped due to shared library event: 
    Inferior loaded /usr/lib64/libc.so.6 

而现在,./a.out也被加载,这样你就可以重新启用的断点:

(gdb) enable 
(gdb) continue 
Continuing. 

Breakpoint 1, main() at t.c:6 
6  printf("Hello\n"); 
相关问题