使用gdb调试运行在不同libc(ld-linux.so)下的应用程序

3
我想在嵌入式系统上使用调试一个应用程序。该应用程序需要更新的和线程,并通过调用Linux动态加载器ld-linux-x86-64.so.2正常工作。我想做的是附加并查看符号和堆栈跟踪,但是加载器“干扰”了。
这里有一个示例test.c文件:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <pthread.h>

void *subThread(void *arg) {
        printf("Thread started after '%d' chars.\n", (long *)arg);
        sleep(2);
        printf("Thread '%d' ended.\n", (long *)arg);
        pthread_exit(NULL);

}
int main() {
        pid_t pid = getpid();
        if (pid > 0) {
                printf("The process id is %d.\n", pid);
                printf("Type 'q' to exit, 't' to spawn a thread.\n");

                char readChar;
                long count = 0;
                do {
                        count++;
                        readChar = getchar();
                        if (readChar == 't') {
                                // Spawn a thread
                                pthread_t thread_id;
                                pthread_create(&thread_id, NULL, subThread, (void *) count);
                                pthread_join(thread_id, NULL);
                        }
                } while(readChar != 'q');

                printf("Main ended.\n");
                return(0);
        } else {
                return(1);
        }
}

我在一个特定的系统中使用特定版本的 glibc 编译了这个源文件,方法如下:

othersystem:~# gcc -O2 -g -lpthread -o test test.c

然后我将test二进制文件移动到我的嵌入式系统中,该系统具有较旧的glibc版本,无法直接运行test,因此我也复制了加载器和所需的库。另请参阅我的gdb设置。

[~/test] # ls
ld-linux-x86-64.so.2*  libc.so.6*  libpthread.so.0*  libthread_db.so.1  test*

[~/test] # cat ~/.gdbinit 
set auto-load safe-path /
set pagination off
set libthread-db-search-path /root/test

现在我运行代码并按下CTRLZ暂停,我想使用进程ID附加gdb。问题是gdb只看到了加载器而没有看到应用程序,因此无法加载调试符号。

[~/test] # /root/test/ld-linux-x86-64.so.2 --library-path /root/test /root/test/test 
The process id is 30622.
Type 'q' to exit, 't' to spawn a thread.
^Z
[1]+  Stopped(SIGTSTP)        /root/test/ld-linux-x86-64.so.2 --library-path /root/test /root/test/test

[~/test] # gdb /root/test/test 30622
GNU gdb (GDB) 10.1
Reading symbols from /root/test/test...
Attaching to program: /root/test/test, process 30622

warning: Build ID mismatch between current exec-file /root/test/test
and automatically determined exec-file /root/test/ld-linux-x86-64.so.2
exec-file-mismatch handling is currently "ask"
Load new symbol table from "/root/test/ld-linux-x86-64.so.2"? (y or n) y
Reading symbols from /root/test/ld-linux-x86-64.so.2...
(No debugging symbols found in /root/test/ld-linux-x86-64.so.2)
Reading symbols from /root/test/libpthread.so.0...
(No debugging symbols found in /root/test/libpthread.so.0)
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/root/test/libthread_db.so.1".
Reading symbols from /root/test/libc.so.6...
(No debugging symbols found in /root/test/libc.so.6)
Reading symbols from /root/test/ld-linux-x86-64.so.2...
(No debugging symbols found in /root/test/ld-linux-x86-64.so.2)
Reading symbols from /lib/libgcc_s.so.1...
0x00007fa1ef590494 in read () from /root/test/libc.so.6
(gdb) bt
#0  0x00007fa1ef590494 in read () from /root/test/libc.so.6
#1  0x00007fa1ef522670 in _IO_file_underflow () from /root/test/libc.so.6
#2  0x00007fa1ef5237b2 in _IO_default_uflow () from /root/test/libc.so.6
#3  0x00007fa1ef51de68 in getc () from /root/test/libc.so.6
#4  0x00007fa1ef68b110 in ?? ()
#5  0x00007fa1ef68b290 in ?? ()
#6  0x00007fa1ef4a2700 in ?? ()
#7  0x00007ffcdae50bb8 in ?? ()
#8  0x0000000000000000 in ?? ()

我不知道如何告诉gdb/root/test/test加载符号;这里有一些有趣的文章(链接1)(链接2)以及在StackOveflow上的答案,但是都没有起作用...我无法获得正确的地址来使用add-symbol-file指令。 我试过这样做:

[~/test] # cat /proc/30622/maps | grep "r-xp" | grep "/root/test/test" | awk -F'-' '{printf $1}'
7fa1ef68b000

[~/test] # objdump -s --section=".text" /root/test/test | grep Contents -A 1 | tail -n 1 | awk -F' ' '{printf $1}'                      
10c0

所以地址应该是 0x7fa1ef68b000 + 0x10c0 = 0x7fa1ef68c0c0,对吗?但是当我在gdb中输入时,可以看到它没有捕捉到调试符号:
(gdb) add-symbol-file /root/test/test 0x7fa1ef68c0c0
add symbol table from file "/root/test/test" at
        .text_addr = 0x7fa1ef68c0c0
(y or n) y
Reading symbols from /root/test/test...
(gdb) bt
#0  0x00007fa1ef590494 in read () from /root/test/libc.so.6
#1  0x00007fa1ef522670 in _IO_file_underflow () from /root/test/libc.so.6
#2  0x00007fa1ef5237b2 in _IO_default_uflow () from /root/test/libc.so.6
#3  0x00007fa1ef51de68 in getc () from /root/test/libc.so.6
#4  0x00007fa1ef68b110 in ?? ()
#5  0x00007fa1ef68b290 in ?? ()
#6  0x00007fa1ef4a2700 in ?? ()
#7  0x00007ffcdae50bb8 in ?? ()
#8  0x0000000000000000 in ?? ()
(gdb) 

是否有一种方法可以加载调试符号而不手动指定地址?如果我将二进制文件编译为硬编码的解释器路径,像这样:

othersystem:~# gcc -O2 -g -lpthread -Wl,-rpath /root/test -Wl,--dynamic-linker=/root/test/ld-linux-x86-64.so.2 -o test2 test.c

然后一切都正常工作:

[~/test] # ldd /root/test/test2
        linux-vdso.so.1 (0x00007ffcaa59c000)
        libpthread.so.0 => /root/test/libpthread.so.0 (0x00007f7265e1d000)
        libc.so.6 => /root/test/libc.so.6 (0x00007f7265c5c000)
        /root/test/ld-linux-x86-64.so.2 (0x00007f7265e40000)

[~/test] # /root/test/test2
The process id is 23264.
Type 'q' to exit, 't' to spawn a thread.
^Z
[1]+  Stopped(SIGTSTP)        ./test2

[~/test] # gdb /root/test/test2 23264
GNU gdb (GDB) 10.1
Reading symbols from /root/test/test2...
Attaching to program: /root/test/test2, process 23264
Reading symbols from /root/test/libpthread.so.0...
(No debugging symbols found in /root/test/libpthread.so.0)
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/root/test/libthread_db.so.1".
Reading symbols from /root/test/libc.so.6...
(No debugging symbols found in /root/test/libc.so.6)
Reading symbols from /root/test/ld-linux-x86-64.so.2...
(No debugging symbols found in /root/test/ld-linux-x86-64.so.2)

Program received signal SIGTSTP, Stopped (user).
0x00007ffba4e7d461 in read () from /root/test/libc.so.6
(gdb) bt
#0  0x00007ffba4e7d461 in read () from /root/test/libc.so.6
#1  0x00007ffba4e0f670 in _IO_file_underflow () from /root/test/libc.so.6
#2  0x00007ffba4e107b2 in _IO_default_uflow () from /root/test/libc.so.6
#3  0x00005613ef88a110 in getchar () at /usr/include/x86_64-linux-gnu/bits/stdio.h:49
#4  main () at test.c:24

编辑

根据Employed Russian的要求,我添加了完整的地图和readelf输出(当然我必须使用一个新的pid):

[~/test] # /root/test/ld-linux-x86-64.so.2 --library-path /root/test /root/test/test 
The process id is 16873.
Type 'q' to exit, 't' to spawn a thread.
^Z
[1]+  Stopped(SIGTSTP)        /root/test/ld-linux-x86-64.so.2 --library-path /root/test /root/test/test

[~/test] # cat /proc/16873/maps
7f5e3767b000-7f5e3767e000 rw-p 00000000 00:00 0 
7f5e3767e000-7f5e376a0000 r--p 00000000 00:10 64323010                   /root/test/libc.so.6
7f5e376a0000-7f5e377e8000 r-xp 00022000 00:10 64323010                   /root/test/libc.so.6
7f5e377e8000-7f5e37834000 r--p 0016a000 00:10 64323010                   /root/test/libc.so.6
7f5e37834000-7f5e37835000 ---p 001b6000 00:10 64323010                   /root/test/libc.so.6
7f5e37835000-7f5e37839000 r--p 001b6000 00:10 64323010                   /root/test/libc.so.6
7f5e37839000-7f5e3783b000 rw-p 001ba000 00:10 64323010                   /root/test/libc.so.6
7f5e3783b000-7f5e3783f000 rw-p 00000000 00:00 0 
7f5e3783f000-7f5e37845000 r--p 00000000 00:10 64323011                   /root/test/libpthread.so.0
7f5e37845000-7f5e37854000 r-xp 00006000 00:10 64323011                   /root/test/libpthread.so.0
7f5e37854000-7f5e3785a000 r--p 00015000 00:10 64323011                   /root/test/libpthread.so.0
7f5e3785a000-7f5e3785b000 r--p 0001a000 00:10 64323011                   /root/test/libpthread.so.0
7f5e3785b000-7f5e3785c000 rw-p 0001b000 00:10 64323011                   /root/test/libpthread.so.0
7f5e3785c000-7f5e37862000 rw-p 00000000 00:00 0 
7f5e37862000-7f5e37863000 r--p 00000000 00:10 64323013                   /root/test/test
7f5e37863000-7f5e37864000 r-xp 00001000 00:10 64323013                   /root/test/test
7f5e37864000-7f5e37865000 r--p 00002000 00:10 64323013                   /root/test/test
7f5e37865000-7f5e37866000 r--p 00002000 00:10 64323013                   /root/test/test
7f5e37866000-7f5e37867000 rw-p 00003000 00:10 64323013                   /root/test/test
7f5e37867000-7f5e37868000 r--p 00000000 00:10 64323009                   /root/test/ld-linux-x86-64.so.2
7f5e37868000-7f5e37886000 r-xp 00001000 00:10 64323009                   /root/test/ld-linux-x86-64.so.2
7f5e37886000-7f5e3788e000 r--p 0001f000 00:10 64323009                   /root/test/ld-linux-x86-64.so.2
7f5e3788e000-7f5e3788f000 r--p 00026000 00:10 64323009                   /root/test/ld-linux-x86-64.so.2
7f5e3788f000-7f5e37890000 rw-p 00027000 00:10 64323009                   /root/test/ld-linux-x86-64.so.2
7f5e37890000-7f5e37891000 rw-p 00000000 00:00 0 
7f5e3905f000-7f5e39080000 rw-p 00000000 00:00 0                          [heap]
7fff1fcd3000-7fff1fcf4000 rw-p 00000000 00:00 0                          [stack]
7fff1fd82000-7fff1fd85000 r--p 00000000 00:00 0                          [vvar]
7fff1fd85000-7fff1fd87000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]

[~/test] # readelf -Wl /root/test/test

Elf file type is DYN (Shared object file)
Entry point 0x1160
There are 11 program headers, starting at offset 64

Program Headers:
  Type           Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align
  PHDR           0x000040 0x0000000000000040 0x0000000000000040 0x000268 0x000268 R   0x8
  INTERP         0x0002a8 0x00000000000002a8 0x00000000000002a8 0x00001c 0x00001c R   0x1
      [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
  LOAD           0x000000 0x0000000000000000 0x0000000000000000 0x000768 0x000768 R   0x1000
  LOAD           0x001000 0x0000000000001000 0x0000000000001000 0x0002fd 0x0002fd R E 0x1000
  LOAD           0x002000 0x0000000000002000 0x0000000000002000 0x000210 0x000210 R   0x1000
  LOAD           0x002dd8 0x0000000000003dd8 0x0000000000003dd8 0x000290 0x0002a8 RW  0x1000
  DYNAMIC        0x002de8 0x0000000000003de8 0x0000000000003de8 0x0001f0 0x0001f0 RW  0x8
  NOTE           0x0002c4 0x00000000000002c4 0x00000000000002c4 0x000044 0x000044 R   0x4
  GNU_EH_FRAME   0x002098 0x0000000000002098 0x0000000000002098 0x000044 0x000044 R   0x4
  GNU_STACK      0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RW  0x10
  GNU_RELRO      0x002dd8 0x0000000000003dd8 0x0000000000003dd8 0x000228 0x000228 R   0x1

 Section to Segment mapping:
  Segment Sections...
   00     
   01     .interp 
   02     .interp .note.ABI-tag .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt 
   03     .init .plt .plt.got .text .fini 
   04     .rodata .eh_frame_hdr .eh_frame 
   05     .init_array .fini_array .dynamic .got .got.plt .data .bss 
   06     .dynamic 
   07     .note.ABI-tag .note.gnu.build-id 
   08     .eh_frame_hdr 
   09     
   10     .init_array .fini_array .dynamic .got

[~/test] # readelf -WS /root/test/test
There are 37 section headers, starting at offset 0x4b18:

Section Headers:
  [Nr] Name              Type            Address          Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            0000000000000000 000000 000000 00      0   0  0
  [ 1] .interp           PROGBITS        00000000000002a8 0002a8 00001c 00   A  0   0  1
  [ 2] .note.ABI-tag     NOTE            00000000000002c4 0002c4 000020 00   A  0   0  4
  [ 3] .note.gnu.build-id NOTE            00000000000002e4 0002e4 000024 00   A  0   0  4
  [ 4] .gnu.hash         GNU_HASH        0000000000000308 000308 000028 00   A  5   0  8
  [ 5] .dynsym           DYNSYM          0000000000000330 000330 000168 18   A  6   1  8
  [ 6] .dynstr           STRTAB          0000000000000498 000498 0000da 00   A  0   0  1
  [ 7] .gnu.version      VERSYM          0000000000000572 000572 00001e 02   A  5   0  2
  [ 8] .gnu.version_r    VERNEED         0000000000000590 000590 000040 00   A  6   2  8
  [ 9] .rela.dyn         RELA            00000000000005d0 0005d0 0000d8 18   A  5   0  8
  [10] .rela.plt         RELA            00000000000006a8 0006a8 0000c0 18  AI  5  23  8
  [11] .init             PROGBITS        0000000000001000 001000 000017 00  AX  0   0  4
  [12] .plt              PROGBITS        0000000000001020 001020 000090 10  AX  0   0 16
  [13] .plt.got          PROGBITS        00000000000010b0 0010b0 000008 08  AX  0   0  8
  [14] .text             PROGBITS        00000000000010c0 0010c0 000231 00  AX  0   0 16
  [15] .fini             PROGBITS        00000000000012f4 0012f4 000009 00  AX  0   0  4
  [16] .rodata           PROGBITS        0000000000002000 002000 000097 00   A  0   0  8
  [17] .eh_frame_hdr     PROGBITS        0000000000002098 002098 000044 00   A  0   0  4
  [18] .eh_frame         PROGBITS        00000000000020e0 0020e0 000130 00   A  0   0  8
  [19] .init_array       INIT_ARRAY      0000000000003dd8 002dd8 000008 08  WA  0   0  8
  [20] .fini_array       FINI_ARRAY      0000000000003de0 002de0 000008 08  WA  0   0  8
  [21] .dynamic          DYNAMIC         0000000000003de8 002de8 0001f0 10  WA  6   0  8
  [22] .got              PROGBITS        0000000000003fd8 002fd8 000028 08  WA  0   0  8
  [23] .got.plt          PROGBITS        0000000000004000 003000 000058 08  WA  0   0  8
  [24] .data             PROGBITS        0000000000004058 003058 000010 00  WA  0   0  8
  [25] .bss              NOBITS          0000000000004070 003068 000010 00  WA  0   0 16
  [26] .comment          PROGBITS        0000000000000000 003068 00001c 01  MS  0   0  1
  [27] .debug_aranges    PROGBITS        0000000000000000 003084 000040 00      0   0  1
  [28] .debug_info       PROGBITS        0000000000000000 0030c4 000626 00      0   0  1
  [29] .debug_abbrev     PROGBITS        0000000000000000 0036ea 000200 00      0   0  1
  [30] .debug_line       PROGBITS        0000000000000000 0038ea 00020c 00      0   0  1
  [31] .debug_str        PROGBITS        0000000000000000 003af6 000308 01  MS  0   0  1
  [32] .debug_loc        PROGBITS        0000000000000000 003dfe 0000e8 00      0   0  1
  [33] .debug_ranges     PROGBITS        0000000000000000 003ee6 000090 00      0   0  1
  [34] .symtab           SYMTAB          0000000000000000 003f78 000780 18     35  52  8
  [35] .strtab           STRTAB          0000000000000000 0046f8 0002bc 00      0   0  1
  [36] .shstrtab         STRTAB          0000000000000000 0049b4 000160 00      0   0  1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
  L (link order), O (extra OS processing required), G (group), T (TLS),
  C (compressed), x (unknown), o (OS specific), E (exclude),
  l (large), p (processor specific)

最终解决方案

为了更容易(未来)阅读,我在这里报告使用Employed Russian的解决方案后的输出。

[~/test] # /root/test/ld-linux-x86-64.so.2 --library-path /root/test /root/test/test 
The process id is 16873.
Type 'q' to exit, 't' to spawn a thread.
^Z
[1]+  Stopped(SIGTSTP)        /root/test/ld-linux-x86-64.so.2 --library-path /root/test /root/test/test

[~/test] # cat /proc/16873/maps | grep "/root/test/test" | awk -F'-' '{print "0x" $1; exit; }'
0x7f5e37862000
[~/test] # readelf -WS /root/test/test | grep '\.text ' | awk '{print "0x" $5}'
0x0010c0

[~/test] # gdb /root/test/test 16873
GNU gdb (GDB) 10.1
Reading symbols from /root/test/test...
Attaching to program: /root/test/test, process 16873

warning: Build ID mismatch between current exec-file /root/test/test
and automatically determined exec-file /root/test/ld-linux-x86-64.so.2
exec-file-mismatch handling is currently "ask"
Load new symbol table from "/root/test/ld-linux-x86-64.so.2"? (y or n) y
Reading symbols from /root/test/ld-linux-x86-64.so.2...
(No debugging symbols found in /root/test/ld-linux-x86-64.so.2)
Reading symbols from /root/test/libpthread.so.0...
(No debugging symbols found in /root/test/libpthread.so.0)
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/root/test/libthread_db.so.1".
Reading symbols from /root/test/libc.so.6...
(No debugging symbols found in /root/test/libc.so.6)
Reading symbols from /root/test/ld-linux-x86-64.so.2...
(No debugging symbols found in /root/test/ld-linux-x86-64.so.2)

Program received signal SIGTTIN, Stopped (tty input).
0x00007f5e37768461 in read () from /root/test/libc.so.6
(gdb) bt
#0  0x00007f5e37768461 in read () from /root/test/libc.so.6
#1  0x00007f5e376fa670 in _IO_file_underflow () from /root/test/libc.so.6
#2  0x00007f5e376fb7b2 in _IO_default_uflow () from /root/test/libc.so.6
#3  0x00007f5e37863110 in ?? ()
#4  0x00007f5e37863290 in ?? ()
#5  0x00007f5e37863160 in ?? ()
#6  0x00007fff1fcf2578 in ?? ()
#7  0x0000000000000000 in ?? ()

(gdb) add-symbol-file /root/test/test 0x7f5e37862000+0x0010c0
add symbol table from file "/root/test/test" at
        .text_addr = 0x7f5e378630c0
(y or n) y
Reading symbols from /root/test/test...

(gdb) bt
#0  0x00007f5e37768461 in read () from /root/test/libc.so.6
#1  0x00007f5e376fa670 in _IO_file_underflow () from /root/test/libc.so.6
#2  0x00007f5e376fb7b2 in _IO_default_uflow () from /root/test/libc.so.6
#3  0x00007f5e37863110 in getchar () at /usr/include/x86_64-linux-gnu/bits/stdio.h:49
#4  main () at test.c:24
#5  0x00007f5e376a209b in __libc_start_main () from /root/test/libc.so.6
#6  0x00007f5e3786318a in _start ()

(gdb) q
A debugging session is active.

        Inferior 1 [process 16873] will be detached.

Quit anyway? (y or n) y
Detaching from program: /root/test/ld-linux-x86-64.so.2, process 16873
[Inferior 1 (process 16873) detached]

[1]+  Stopped(SIGTTIN)        /root/test/ld-linux-x86-64.so.2 --library-path /root/test /root/test/test

所以我需要回复请求文件不匹配并使用真实可执行文件的路径,然后使用/proc/pid/maps(第一个结果)和readelf检索到的地址(基址+偏移量),接着使用add-symbol-file命令。


你本地和远程系统的配置/发行版是什么?为了获取gdb的符号,根据发行版,您必须安装相应的“调试”软件包。在Fedora上,如果找到没有调试信息的.so文件,gdb将打印要安装的调试软件包的名称。顺便说一句,在本地系统上进行本机构建,然后复制库。也许你应该将远程的[旧]库文件复制到本地并进行交叉构建[即使它是相同的架构]。如果远程是arm,那么你必须这样做。 - Craig Estey
@CraigEstey 我的问题不在于从调试包中获取符号,因为当我运行 test2 示例(其中解释器 /root/test/ld-linux-x86-64.so.2 已硬编码)时,gdb 工作并加载我的测试应用程序符号。问题在于如何告诉 gdb 当应用程序从另一个加载程序运行并且 gdb 附加到其进程 ID 时,要加载应用程序的调试符号。 - virtualdj
1个回答

1

但是没有一种方法有效...

add-symbol-file ... 的解决方案应该有效。我怀疑您没有提供正确的 .text 地址。

cat /proc/30622/maps | grep "r-xp" | grep "/root/test/test"

这假定 /root/test/test 的第一个段具有 RX 权限。

过去确实是这样,但现代系统上不再如此(例如,请参见 this answer)。

您没有提供来自 readelf -Wl /root/test/test 的输出,但我敢打赌它看起来与另一个答案中的 4 段示例类似(其中第一个 LOAD 段具有只读权限)。

通常,您需要找到 test 可执行文件在内存中第一个 LOAD 段的地址,并将 .text 的地址添加到 基址上。

更新:

通过新提供的/proc/$pid/mapsreadelf输出,我们可以看到我的猜测是正确的:这个二进制文件有4个LOAD段,而第一个段没有r-x权限。
然后的计算是:$address_of_the_first_PT_LOAD + $address_of_.text。对于进程16873来说,就是:
(gdb) add-symbol-file /root/test/test 0x7f5e37862000+0x10c0

这种写法过于复杂,有更简单的方法:

objdump -s --section=".text" /root/test/test | grep Contents -A 1 ...

readelf -WS /root/test/test | grep '\.text ' | nawk '{print "0x" $4}'

更新:

我需要在测试机器上运行gdb(该机器没有nawk和其他功能)

这里的一部分困难在于您有一个PIE二进制文件(在运行时重新定位)。

如果问题在非PIE二进制文件(使用-fno-pie -no-pie编译)中重现,则可以在开发机器上计算地址并在测试机器上重复使用。您不需要每次运行二进制文件时都计算地址的脚本。


如果我将二进制文件编译为解释器路径硬编码,通常这是最好的方法。为什么不使用它呢?如果你想让二进制文件在开发和测试机器上都能运行,请在两者上都复制“/root/test”。

我已经按照你的要求更新了问题,并提供了 /proc/pid/mapsreadelf 的完整输出,请问你能否重写你的答案,让我明白我应该如何计算需要用于 add-symbol-file 的地址?我需要在测试机器上运行 _gdb_(它没有 nawk 和其他一些功能,因为它是一个没有完整 Linux 环境的 NAS),如果可能的话,我也想避免更改解释器。这只是一个示例,我想要调试的应用程序更加复杂,但问题只发生在测试机器上,因此我想在那里进行调试。 - virtualdj
谢谢,这个可行!那么,提取 $address_of_the_first_PT_LOAD 是使用以下命令正确吗:cat /proc/16873/maps | grep "/root/test/test" | awk -F'-' '{print "0x" $1; exit; }' 以检索第一个匹配项? - virtualdj
1
@virtualdj 这对大多数二进制文件都有效,但如果二进制文件mmap()s自身,并且该映射在内存中较低,则可能会遇到问题。这通常是不寻常的事情,但是“自我意识”的二进制文件(例如,符号化其自身崩溃的二进制文件)可能会这样做。 - Employed Russian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接