GDB зависает при удаленной отладке, несоответствие версий библиотеки - PullRequest
3 голосов
/ 26 июня 2019

Я использую Linux и пытаюсь удаленно отладить программу.

Я запускаю gdbserver на цели из .xinitrc с помощью

gdbserver localhost:9134 /root/game/game

На моем локальном компьютере, на котором я работаю в виртуальной коробке vm, я подключаюсь к цели из gdb с помощью

target remote 192.168.1.20:9134

и подключается нормально.Я могу установить точку останова на главном с помощью

b main

, а затем я могу продолжить, и она сломается там.Я могу сделать шаг за шагом, пока он не доберется до вызова SDL_Init (), из которого он никогда не вернется обратно в gdb.Если я не сделаю ни одного шага для SDL_Init, а вместо этого установлю точку останова в программе, программа запустится и будет работать нормально (поэтому она проходит мимо SDL_Init).Но когда он достигает точки останова, он зависает на целевой машине, и GDB на моей локальной машине никогда не показывает подсказку.Вся вещь зависает и должна быть перезапущена.Однако он не полностью заморожен, так как указатель мыши все еще перемещается по цели, и вы можете пропинговать его, но соединение с gdb больше не работает.Поэтому кажется, что графические системы каким-то образом мешают этому, поскольку точки останова до инициализации графической системы работают, но не после.

Я попытался установить для параметра remotetimeout значение 500 секунд, и он демонстрирует то же поведение,Когда я отправляю эхо-запрос на удаленную цель с моего локального компьютера, сообщаемое время составляет от 0,3 до 0,4 мс.Так что это не кажется чем-то необычным, но я бы не стал исключать другие неправильно настроенные сетевые настройки с моей стороны.

Это на устаревшей системе (но эй, она все еще зарабатывает деньги) с версией gdbserver 6.8-19.fc10 и версией gdb 6.8-29.fc10.Обновление версий, хотя и очень большая головная боль, может быть возможным, но, вероятно, в этом нет необходимости (любые обновления, которые я делаю для своего компьютера, должны быть также выполнены для системы регулятора состояния, поскольку они используют настройку gdb для своих целей тестирования, но этоне возможно).Удаленная отладка работала в прошлом до того, как я взял на себя управление проектом, и никто, кто работал над ним раньше, все еще не может спросить.Версия gdbserver определенно работала, так как я использую точную программу, использованную ранее.

Обновление 1:Я обновил версию GDB на хост-машине до версии 7.0.1, и она по-прежнему демонстрирует то же поведение.Я не смог сделать версию 8, так как ей нужен компилятор C ++ 11, а устаревшая система до этого времени.

Обновление 2:Я попробовал это на другой виртуальной машине, и я даже собрал новую выделенную установку Linux (так что нет vm), перестроил программное обеспечение, и я получил то же поведение.Похоже, что проблема, вероятно, в конфигурации целевой машины.

Обновление 3:Я выкопал последовательный кабель и, наконец, получил настройки удаленной отладки через последовательный порт.Это все еще не работает, но дает мне больше сообщений об ошибках.Я получаю сообщение об ошибке

gdbserver: error initializing thread_db library: version mismatch between libthread_db and libpthread

, которое, как мне кажется, имеет смысл, поскольку мои точки останова перестают работать после инициализации графической системы, что связано с созданием некоторых потоков.После поиска этой ошибки я попытался использовать set solib-absolute-prefix, set solib-search-path и set sysroot в корневой каталог на хост-компьютере копии файловой системы на целевой машине (на хосте, то есть / fw_dev /fgs / cf / initrd / expand, который содержит файловую систему, из которой сделан initrd)Но затем, когда я пытаюсь установить точки останова, я получаю Error accessing memory address 0xb5eb60: Input/output error. Я также пытался установить эти переменные в подкаталог lib, который тоже не работает.Я также попытался просто скопировать локальные библиотеки потоков из каталога /lib хоста в /lib на цели, но тогда x windows даже не запустился.

Обновление № 4:Я попытался запустить GDB из корня копии целевой файловой системы на хосте (/ fw_dev / fgs / cf / initrd / expand), и GDB по-прежнему зависает на точках останова, но я больше не получаю сообщение об ошибке о несоответствиях libthread_db и libpthread,Итак, вернемся к чертежной доске.

Обновление № 5Может быть, я добираюсь туда, где мне следует задать отдельный вопрос, но я скомпилировал gdb, а затем запустил gbd сам по себе.Затем использовал file, чтобы установить его для программы на хосте, установить удаленную цель, установить мои контрольные точки и затем запустить continue.Когда я добираюсь до точки останова, GDB зависает как всегда.Но теперь, когда я нажимаю ctrl-c в gdb, я получаю эту обратную трассировку

#0  0x00110416 in __kernel_vsyscall ()
#1  0x00b3f39d in ___newselect_nocancel () from /lib/libc.so.6
#2  0x08203b9a in ser_base_wait_for (scb=0x96a2930, timeout=1) at ser-base.c:206
#3  0x08203c89 in do_ser_base_readchar (scb=0x96a2930, timeout=-1) at ser-base.c:256
#4  0x08204046 in generic_readchar (scb=0x96a2930, timeout=-1, do_readchar=0x8203c60 <do_ser_base_readchar>) at ser-base.c:326
#5  0x082040b0 in ser_base_readchar (scb=0x96a2930, timeout=-1) at ser-base.c:391
#6  0x081ecac2 in serial_readchar (scb=0x96a2930, timeout=-1) at serial.c:376
#7  0x080c4357 in readchar (timeout=<value optimized out>) at remote.c:5922
#8  0x080c5e35 in getpkt_or_notif_sane_1 (buf=0x839f140, sizeof_buf=0x839f144, forever=1, expecting_notif=0) at remote.c:6440
#9  0x080d1e0a in getpkt_sane (ops=0x839f180, ptid=..., status=0xbffff388, options=0) at remote.c:6534
#10 remote_wait_as (ops=0x839f180, ptid=..., status=0xbffff388, options=0) at remote.c:4736
#11 remote_wait (ops=0x839f180, ptid=..., status=0xbffff388, options=0) at remote.c:4843
#12 0x08184d4b in target_wait (ptid=..., status=0xbffff388, options=0) at target.c:2098
#13 0x0815daf2 in wait_for_inferior (treat_exec_as_sigtrap=0) at infrun.c:2028
#14 0x0815ddd4 in proceed (addr=4294967295, siggnal=TARGET_SIGNAL_DEFAULT, step=0) at infrun.c:1652
#15 0x08153729 in continue_1 (all_threads=0) at infcmd.c:668
#16 0x08153ea2 in continue_command (args=0x0, from_tty=0) at infcmd.c:760
#17 0x0808e9e8 in execute_command (p=0x83b89a1 "", from_tty=0) at top.c:453
#18 0x0816b028 in command_handler (command=0x83b89a0 "c") at event-top.c:511
#19 0x0816bd5a in command_line_handler (rl=0x8ce83e8 "\340&\266\b\340\230\321\b") at event-top.c:736
#20 0x0822d5a5 in rl_callback_read_char () at callback.c:205
#21 0x0816b17b in rl_callback_read_char_wrapper (client_data=0x0) at event-top.c:178
#22 0x0816ac54 in handle_file_event (data=...) at event-loop.c:812
#23 0x08169e6b in process_event () at event-loop.c:394
#24 0x0816aba4 in gdb_do_one_event (data=0x0) at event-loop.c:459
#25 0x0816500b in catch_errors (func=0x816a950 <gdb_do_one_event>, func_args=0x0, errstring=0x82ccc3d "", mask=6) at exceptions.c:510
#26 0x080f072a in tui_command_loop (data=0x0) at ./tui/tui-interp.c:153
#27 0x08165684 in current_interp_command_loop () at interps.c:291
#28 0x0808653b in captured_command_loop (data=0x0) at ./main.c:226
#29 0x0816500b in catch_errors (func=0x8086530 <captured_command_loop>, func_args=0x0, errstring=0x82ccc3d "", mask=6) at exceptions.c:510
#30 0x08085ecc in captured_main (data=0xbffff7a4) at ./main.c:902
#31 0x0816500b in catch_errors (func=0x80853d0 <captured_main>, func_args=0xbffff7a4, errstring=0x82ccc3d "", mask=6) at exceptions.c:510
#32 0x080851d1 in gdb_main (args=0xbffff7a4) at ./main.c:911
#33 0x08085195 in main (argc=128, argv=0x0) at gdb.c:33

Так что кажется, что gdb висит внутри __kernel_vsyscall ().Выполнение diff на libc.so.6 в каталоге / lib на хосте и libc.so.6 на цели выявляет различия.Я пытался использовать LD_PRELOAD и LD_LIBRARY_PATH, но эта обратная трассировка всегда показывает /lib/libc.so.6 вместо того, чтобы указывать на копию, имеющуюся у цели.Может быть, я неправильно их устанавливаю, но я пытался установить их в gdb с помощью set env, а также установить их в командной строке и экспортировать, но безрезультатно.Я также попытался поместить libc с хост-компьютера на целевую машину, и он даже не загрузился, он получил ошибку в libc.Итак, как мне заставить GDB загружать разные библиотеки?

Обновление № 6:Поэтому я сделал загрузочный USB-ключ, используя образ диска целевой системы в качестве базы.Я внес в него минимальные изменения, чтобы он работал на стандартном ПК, и добавил в него необходимые библиотеки gdb и gdb.Итак, теперь ibc одинаков как на хосте, так и на целевых машинах, и он все еще висит на мне.

FinalХотя я знаю, что GDB 6.8 работал в прошлом, я не могу понять конфигурацию.После обновления и gdb и gdbserver до 7.12 все заработало.

Ответы [ 2 ]

1 голос
/ 09 июля 2019

Возможно обновление версий, хотя и очень большая головная боль, но, вероятно, в этом нет необходимости ...

Это правильный вариант. Все остальные проблемы, с которыми вы сталкиваетесь, связаны с этим.

Я пробовал это на другой виртуальной машине, и я даже создал новую выделенную установку для Linux (так что нет vm), пересобрал программное обеспечение, и я получил то же самое поведение. Похоже, проблема, возможно, в конфигурации целевой машины.

Вы должны использовать ту же версию, архитектуру и т. Д., Что и система, в которой вы пытаетесь развернуть свой код.

Но затем, когда я пытаюсь установить точки останова, я получаю сообщение об ошибке при обращении к адресу памяти 0xb5eb60: ошибка ввода / вывода.

За этот ответ ,

Может быть вызвано 32/64 битными смешиваниями. Например, убедитесь, что вы не подключили 32-битный двоичный файл с идентификатором 64-битного процесса или наоборот.

Я также попытался поместить libc с хост-компьютера на целевой компьютер, и он даже не загружается, он получает ошибку в libc.

Не делай этого. Как вы узнали, это не сработает.

Так как мне заставить GDB загружать разные библиотеки?

За этот вопрос , вы можете использовать LD_LIBRARY_PATH.

0 голосов
/ 09 июля 2019

Вот некоторые интересные предложения.Вы пытались подключить gdbserver к strace, чтобы увидеть, что происходит во время зависания?Как говорят другие - это может быть хорошим способом сделать еще один шаг в выяснении проблемы.Это можно сделать с помощью следующей команды на целевом компьютере:

strace -p `pidof gdbserver`

Также может помочь отправка сигнала CONT на gdbserver при зависании:

kill -CONT `pidof gdbserver`
...