LINUX.ORG.RU

удаленная отладка linux


0

1

Проблема в том, что я никак не могу поставить breakpoint на нужную мне функцию при отладке ядра через виртуальную машину. Так же, не могу воспользоваться и функциями disass, next и т.п..

Имею:
Ubuntu 10.10 2.6.35-22-generic
GDB 7.2
Qemu 0.12.5 (qemu-kvm-0.12.5)

На виртуалку заливаю ядро 2.6.35 с опциями:
CONFIG_DEBUG_INFO
CONFIG_FRAME_POINTER

Запускаю так:
qemu -s -S -kernel vmlinuz-2.6.35 -initrd initrd.gz

Пример gdb-сессии:

$ gdb vmlinux
GNU gdb (GDB) 7.2-ubuntu
Copyright (C) 2010 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 «i686-linux-gnu».
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/snoway/development/SYS/kernels/linux-2.6.35/vmlinux...done.
Setting up the environment for debugging gdb.
Function «internal_error» not defined.
Make breakpoint pending on future shared library load? (y or [n]) [answered N; input not from terminal]
Function «info_command» not defined.
Make breakpoint pending on future shared library load? (y or [n]) [answered N; input not from terminal]
.gdbinit:8: Error in sourced command file:
Argument required (one or more breakpoint numbers).
(gdb) show architecture
The target architecture is set automatically (currently i386)
(gdb) target remote :1234
Remote debugging using :1234
0x0000fff0 in ?? ()
(gdb) disass
No function contains program counter for selected frame.
(gdb) n
Cannot find bounds of current function
(gdb) br start_kernel
During symbol reading, DW_AT_name missing from DW_TAG_base_type.
During symbol reading, unsupported tag: 'DW_TAG_const_type'.
During symbol reading, cannot get low and high bounds for subprogram DIE at 95838.
During symbol reading, Child DIE 0x17c6b and its abstract origin 0x1765e have different parents.
Breakpoint 1 at 0xc12114e7: file init/main.c, line 540.
(gdb) info br
Num Type Disp Enb Address What
1 breakpoint keep y 0xc12114e7 in start_kernel at init/main.c:540
(gdb) c
Continuing.
^C
Program received signal SIGINT, Interrupt.
0xc011be7d in ?? ()
(gdb) bt
#0 0xc011be7d in ?? ()
#1 0xc011adc0 in ?? ()
#2 0xc027047e in ?? ()
#3 0xc0121027 in ?? ()
#4 0xc012c7b0 in ?? ()
#5 0xc0102fb6 in ?? ()
(gdb) info file
Symbols from «/home/snoway/development/SYS/kernels/linux-2.6.35/vmlinux».
Remote serial target in gdb-specific protocol:
Debugging a target over a serial line.
   While running this, GDB does not access memory from...
Local exec file:
   `/home/snoway/development/SYS/kernels/linux-2.6.35/vmlinux', file type elf32-i386.
warning: Cannot find section for the entry point of /home/snoway/development/SYS/kernels/linux-2.6.35/vmlinux.

   Entry point: 0x1000000
   0xc1000000 - 0xc117276d is .text
   0xc1172770 - 0xc1172794 is .notes
   0xc11727a0 - 0xc11739f8 is __ex_table
   0xc1174000 - 0xc11d9ce9 is .rodata
   0xc11d9cf0 - 0xc11dbd9c is __bug_table
   0xc11dbd9c - 0xc11dc6e4 is .pci_fixup
   0xc11dc6e4 - 0xc11e02d4 is __ksymtab
   0xc11e02d4 - 0xc11e1dfc is __ksymtab_gpl
   0xc11e1dfc - 0xc11e3bf4 is __kcrctab
   0xc11e3bf4 - 0xc11e4988 is __kcrctab_gpl
   0xc11e4988 - 0xc11f0982 is __ksymtab_strings
   0xc11f09a0 - 0xc11f34b0 is __init_rodata
   0xc11f34b0 - 0xc11f4000 is __param
   0xc11f4000 - 0xc1210cac is .data
   0xc1211000 - 0xc12303b9 is .init.text
   0xc12303c0 - 0xc124e200 is .init.data
   0xc124e200 - 0xc124e21c is .x86_cpu_dev.init
   0xc124e220 - 0xc1250734 is .altinstructions
   0xc1250734 - 0xc12510ca is .altinstr_replacement
   0xc12510ca - 0xc125152c is .exit.text
   0xc1252000 - 0xc128fc60 is .bss
   0xc1290000 - 0xc1330000 is .brk
(gdb)

При попытке сделать jump по адресу, например 0x1000000, qemu падает с ошибкой о выходе за пределы RAM или ROM. Ситуация повторяется и при qemu-0.13.0 (или более ранних версиях). Пробывал отладку через VMware 7.1.3, таже проблема. Искал по форумам схожую проблему, нашел рекомандации к ручной сборке qemu (из исходников)... пересобрал - не помогло. Да и проблема, скорее, не в виртуальной машине, а в gdb.

Есть у когонить идеи?

никогда не занимался отладкой ядра, но первой строкой что я видел в мануале это было то что «breakpoints are not working». И это логично если дебаггер стоит на этой же машине что и ядро.

А можно ли как-то при помощи виртуалки обойти это я хз.

true_admin ★★★★★ ()
Ответ на: комментарий от true_admin

В данном случае breakpoint'ы ставить можно... Не факт, конечно, что можно поставить именно на start_kernel, но это уже другой вопрос. В приведенном выше примере, я так сделал для простоты, чтобы показать суть происходящего...
***
Есть еще идеи?

userqest ()
Ответ на: комментарий от userqest

а, вижу, тот самый случай. А vmlinux точно от того ядра что и vmlinuz-2.6.35?

true_admin ★★★★★ ()
Ответ на: комментарий от true_admin

Да, vmlinux от vmlinuz-2.6.35.
***
Смотрел, на ChangeLog'и от gdb 7.x, там много наворотили с GDB remoute stub и GDBServer... Может это повлияло на совместимость? Но я думаю, что разработчики предусмотрели данный вопрос...

userqest ()

>При попытке сделать jump по адресу, например 0x1000000, qemu падает с ошибкой о выходе за пределы RAM или ROM.

Число 0x1000000 очень странное для виртуального адреса. Не уверен, что так можно делать jump.

ttnl ★★★★★ ()
Ответ на: комментарий от ttnl

Да, да, точняк, ведро-то по верхним адресам лежит!1 Щас уже не могу найти картинку, но вот тут чуток про это дело:

http://stackoverflow.com/questions/1658757/linux-3-1-virtual-address-split

В общем, я так понял, ведро обычно лежит между 0xC0000000 и 0xffffffff

true_admin ★★★★★ ()
Ответ на: комментарий от true_admin

Ну да. Есть ещё маленькая тонкость - адреса кода ядра и малочной памяти это не одно и тоже. Виртуальные адреса начала кода ядра можно посмотреть в файле vmlinux.lds.S.

ttnl ★★★★★ ()
Ответ на: комментарий от ttnl

малочной памяти

в смысле той которая через malloc возвращается?

true_admin ★★★★★ ()
Ответ на: комментарий от true_admin

Вообще вся физическая память мапится с PAGE_OFFSET (0xC0000000). Дополнительно структуры, имеющие отношения к коду ядра, маппяться по адресу из vmlinux.lds.S.

Говорю по своему опыту (не-x86), но скорей всего для x86 должно быть также (за исключением того, что на x86 есть верхняя память).

ttnl ★★★★★ ()

> Да и проблема, скорее, не в виртуальной машине, а в gdb

Проблема, скорее, в том, что ты не читал документацию.

http://kernel.org/pub/linux/kernel/people/jwessel/kgdb/

Вот тут доходчиво написано, как удалённо отлаживать ядро. Для того, чтобы добавить поддержку отладочных параметров при старте ядра, необходимо собирать его с флагом CONFIG_DEBUG_BOOT_PARAMS.

fang ()
Ответ на: комментарий от fang

Нашел решение!!!

Для символов (vmlinux) нужно добавить смещение.
В моем случае:

add-symbole-file vmlinux 0xc0100000


userqest ()
Ответ на: комментарий от fang

Сорри, что в главном посте не указал, но CONFIG_DEBUG_BOOT_PARAMS у меня было выставлено...

userqest ()
Ответ на: комментарий от userqest

а ты не пробовал отладчик из qemu дернуть? т.е. из консоли qemu

dimon555 ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.