FreeBSD. kgdb KLD debugging


masterx - Posted on 27 Август 2010

Как и прочая FreeBSD-шная литра, FreeBSD Developers' Handbook, морально устарела и пользоваться ей, по крайней мере для debugging the KLD modules большого смысла нет. Копи-пэйст моего дебагинга:

# kgdb /usr/obj/home/alexandre/p4/ringmap/current/sys/I686RINGMAP_CURRENT/kernel.debug vmcore.40
...
Fatal trap 12: page fault while in kernel mode
cpuid = 0; apic id = 00
fault virtual address   = 0x28
fault code              = supervisor read, page not present
instruction pointer     = 0x20:0xc4c9e4fc
stack pointer           = 0x28:0xe63b4bfc
frame pointer           = 0x28:0xe63b4c04
code segment            = base 0x0, limit 0xfffff, type 0x1b
                        = DPL 0, pres 1, def32 1, gran 1
processor eflags        = interrupt enabled, resume, IOPL = 0
current process         = 0 (em1 taskq)
trap number             = 12
panic: page fault
cpuid = 0
Uptime: 6m27s
Physical memory: 1015 MB
Dumping 81 MB: 66 50 34 18 2

Как будто бы все ок, имеем причину паники (page fault), адрес инструкции, которая спровоцировала панику. Посмотрим, листинг программы:

(kgdb) list *0xc4c9e4fc
No source file for address 0xc4c9e4fc.

Упс, kgdb оказывается не знает какому файлу с исходниками соответствует инструкция по адресу 0xc4c9e4fc. На самом деле это не правда - знает

(kgdb) info files
...
        0xc4c83094 - 0xc4c83538 is .hash in /boot/kernel/if_ringmap.ko
        0xc4c83538 - 0xc4c83f78 is .dynsym in /boot/kernel/if_ringmap.ko
        0xc4c83f78 - 0xc4c847c4 is .dynstr in /boot/kernel/if_ringmap.ko
        0xc4c847c4 - 0xc4c89bd4 is .rel.dyn in /boot/kernel/if_ringmap.ko
        0xc4c89be0 - 0xc4cbee83 is .text in /boot/kernel/if_ringmap.ko
        0xc4cbeea0 - 0xc4cc0fe8 is .rodata in /boot/kernel/if_ringmap.ko
        0xc4cc0fe8 - 0xc4cc1048 is set_sysinit_set in /boot/kernel/if_ringmap.ko
        0xc4cc1048 - 0xc4cc1068 is set_modmetadata_set in /boot/kernel/if_ringmap.ko
        0xc4cc2080 - 0xc4cc2c60 is .data in /boot/kernel/if_ringmap.ko
        0xc4cc2c80 - 0xc4cc2cf8 is .dynamic in /boot/kernel/if_ringmap.ko
        0xc4cc2cf8 - 0xc4cc2d04 is .got in /boot/kernel/if_ringmap.ko
        0xc4cc2d20 - 0xc4cc3168 is .bss in /boot/kernel/if_ringmap.ko

У kgdb нет всей нужной информации о символах, которые (по крайней мере начиная с ветки 8) по всей видимости находятся не в .ko файле, а в .kld. Нам нужен адрес по которому расположена секция .text. Видимо, там и записана таблица символов с debug information. Адрес: 0xc4c89be0. Загружаем нужный нам .kld:

(kgdb) add-symbol-file ...../modules/ringmap/if_ringmap.kld 0xc4c89be0
        .text_addr = 0xc4c89be0
(y or n) y
Reading symbols from .....  done.

Теперь смотрим стек:

(kgdb) bt
#0  doadump () at pcpu.h:231
#1  0xc05bfe2a in boot (howto=260) at /home/alexandre/p4/ringmap/current/sys/kern/kern_shutdown.c:416
#2  0xc05c0062 in panic (fmt=Variable "fmt" is not available.
) at /home/alexandre/p4/ringmap/current/sys/kern/kern_shutdown.c:590
#3  0xc07d0ce3 in trap_fatal (frame=0xe63b4bbc, eva=40) at /home/alexandre/p4/ringmap/current/sys/i386/i386/trap.c:945
#4  0xc07d1110 in trap (frame=0xe63b4bbc) at /home/alexandre/p4/ringmap/current/sys/i386/i386/trap.c:326
#5  0xc07bacbb in calltrap () at /home/alexandre/p4/ringmap/current/sys/i386/i386/exception.s:165
#6  0xc4c9e4fc in ringmap_filter () from /boot/kernel/if_ringmap.ko
#7  0xc4c9f3cc in rm_8254_delayed_interrupt_per_packet () from /boot/kernel/if_ringmap.ko
#8  0xc4c9b1d6 in lem_handle_rxtx () from /boot/kernel/if_ringmap.ko
#9  0xc05f68c3 in taskqueue_run (queue=0xc4574540) at /home/alexandre/p4/ringmap/current/sys/kern/subr_taskqueue.c:239
#10 0xc05f6a18 in taskqueue_thread_loop (arg=0xc4cd75a8) at /home/alexandre/p4/ringmap/current/sys/kern/subr_taskqueue.c:360
#11 0xc059b774 in fork_exit (callout=0xc05f69b0 <taskqueue_thread_loop>, arg=0xc4cd75a8, frame=0xe63b4d28)
    at /home/alexandre/p4/ringmap/current/sys/kern/kern_fork.c:843
#12 0xc07bad30 in fork_trampoline () at /home/alexandre/p4/ringmap/current/sys/i386/i386/exception.s:270

Подвела функция ringmap_filter (фрейм #6). Запрыгиваем в #6 и далее все как обычно.

(kgdb) f 6 
#6  0xc4c9e4fc in ringmap_filter () from /boot/kernel/if_ringmap.ko
...
545             printf("ifunit: %d\n", rcvif->if_dunit);
(kgdb) list 
540     ringmap_filter(struct mbuf *m)
541     {
542             struct ifnet *rcvif;
543
544             rcvif = m->m_pkthdr.rcvif;
545             printf("ifunit: %d\n", rcvif->if_dunit);
546
547             return (0);
548     }
549
(kgdb) p m 
$1 = (struct mbuf *) 0xc4ab8500
(kgdb) p *m
$2 = {m_hdr = {mh_next = 0x0, mh_nextpkt = 0x0, mh_data = 0xc4aeb802 "\001\200�, mh_len = 2046, mh_flags = 3, mh_type = 1, pad = "\000"}, M_dat = {MH = {
      MH_pkthdr = {rcvif = 0x0, header = 0x0, len = 2046, flowid = 0, csum_flags = 0, csum_data = 0, tso_segsz = 0, PH_vt = {vt_vtag = 0, vt_nrecs = 0}, 
        tags = {slh_first = 0x0}}, MH_dat = {MH_ext = {ext_buf = 0xc4aeb800 "", ext_free = 0, ext_arg1 = 0x0, ext_arg2 = 0x0, ext_size = 2048, 
          ref_cnt = 0xc4ae7684, ext_type = 6}, MH_databuf = "\000���, '\0' <repeats 13 times>, "\b\000\000\204v��006", '\0' <repeats 174 times>}}, 
    M_databuf = "\000\000\000\000\000\000\000\000�\a", '\0' <repeats 23 times>, "���, '\0' <repeats 13 times>, "\b\000\000\204v��006", '\0' <repeats 174 times>}}

Ага, rcvif = 0x0, вот в чем дело. Будем разбираться...

Отправить комментарий

Google Friend Connect (leave a quick comment)
loading...
Содержание этого поля является приватным и не предназначено к показу.