Я пытаюсь отладить программу, работающую удаленно на плате с процессором MIPS, используя musl для своей библиотеки c. Если я запускаю gdbserver на плате, устанавливаю sys root через set sysroot /path/to/sysroot
и подключаюсь в прямом эфире из gdb, я получаю осмысленную трассировку стека (что потребовало нескольких часов усилий из-за отсутствия в MIPS директив CFI и необходимости их добавления) , но это отдельная проблема), и я могу видеть символы загрузки GDB из libc.so
из sys root.
С другой стороны, если я позволю этой программе cra sh и сгенерирую ядро dump (я использовал kill -6 <pid>
для принудительной проверки), GDB будет загружать символы из двоичного файла, но не из его общих библиотек, даже libc.so
. В то время как другие общие библиотеки хороши, но не обязательны, без отладочной информации из lib c .so, GDB не может разрешить трассировки стека, и все они выглядят как мусор.
Успешный живой сеанс GDB
$ mipsel-poky-linux-gdb -iex "set sysroot /path/to/sysroot" /path/to/testprog
GNU gdb (GDB) 8.2.1
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "--host=x86_64-pokysdk-linux --target=mipsel-poky-linux".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from /path/to/testprog...done.
(gdb)
(gdb) target extended-remote remote-hostname:10000
Remote debugging using remote-hostname:10000
Reading symbols from /path/to/sysroot/lib/ld.so.1...done.
__cp_end () at src/thread/mips/syscall_cp.s:38
38 beq $7, $0, 1f
(gdb) bt
#0 __cp_end () at src/thread/mips/syscall_cp.s:38
#1 0x77eff348 in __syscall_cp_c (nr=4029, u=<optimized out>, v=<optimized out>, w=<optimized out>, x=0, y=0, z=0)
at src/thread/pthread_cancel.c:33
#2 0x77f0b4b0 in pause () at src/unistd/pause.c:7
#3 0x556ecd3c in core_run (argc=1, argv=0x7f7bf4a4) at /path/to/source-file.cpp:461
#4 0x77e93d28 in libc_start_main_stage2 (main=0x556b1ac0 <main(int, char**)>, argc=1, argv=0x7f7bf4a4)
at src/env/__libc_start_main.c:94
#5 0x556eb890 in _start_c (p=<optimized out>) at crt/crt1.c:18
#6 0x556eb850 in _start () at /path/to/header-file.hpp:130
Backtrace stopped: frame did not save the PC
(примечание: в приведенном выше тексте я заменил внутренние пути / имена файлов / et c на заполнители)
Неудачный сеанс работы с дампом основной памяти
$ mipsel-poky-linux-gdb -iex "set verbose on" -iex "set sysroot /path/to/sysroot" /path/to/testprog core
GNU gdb (GDB) 8.2.1
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "--host=x86_64-pokysdk-linux --target=mipsel-poky-linux".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from /path/to/testprog...done.
Reading in symbols for /path/to/source/main.cpp...done.
[New LWP 1285]
[New LWP 1408]
[New LWP 1409]
[New LWP 1410]
[New LWP 1412]
[New LWP 1407]
[New LWP 1401]
[New LWP 1402]
[New LWP 1403]
[New LWP 1404]
Using PIE (Position Independent Executable) displacement 0x555c4000 for "/path/to/testprog".
warning: platform-specific solib_create_inferior_hook did not load initial shared libraries.
Reading symbols from system-supplied DSO at 0x7ff2b000...(no debugging symbols found)...done.
Core was generated by `/remote/path/to/testprog'.
Program terminated with signal SIGABRT, Aborted.
#0 0x77e80204 in ?? ()
[Current thread is 1 (LWP 1285)]
(gdb) bt
warning: GDB can't find the start of the function at 0x77e80204.
GDB is unable to find the start of the function at 0x77e80204
and thus can't determine the size of that function's stack frame.
This means that GDB may be unable to access that stack frame, or
the frames below it.
This problem is most likely caused by an invalid program counter or
stack pointer.
However, if you think GDB should simply search farther back
from 0x77e80204 for code which looks like the beginning of a
function, you can increase the range of the search using the `set
heuristic-fence-post' command.
#0 0x77e80204 in ?? ()
(gdb)
(примечание: в приведенном выше I заменил внутренние пути / имена файлов / et c на местозаполнители)
Вещи, которые я пробовал
Я пробовал несколько вещей, включая использование set solib-search-path
вместо set sysroot
, напрямую сообщая gdb о загрузке библиотека через add-symbol-file /path/to/libc.so
и даже add-symbol-file /path/to/libc.so 0xdeadbeef
, где 0xdeadbeef - это адрес, на который была загружена библиотека, полученная через readelf. В этом последнем случае GDB наконец загрузил символы, но явно что-то было не так, вероятно, адрес, который я передал, был неправильным. Дело в том, что мне не нужно этого делать, GDB должен найти эту информацию в дампе ядра и загрузить библиотеки! Как я могу заставить это сделать это, и почему это не сделало бы это во-первых?