모듈 내에서 발생한 패닉이나 동적 모듈을 사용하는 시스템에 대해 원격 GDB 등을 이용해 디버깅할 때, GDB에게 어떻게 이들 모듈들에 대한 심볼 정보를 얻을 것인지를 알려줘야 합니다.
첫째, 디버깅 정보를 포함하여 모듈들을 빌드해야 합니다.
# cd /sys/modules/linux
# make clean; make COPTS=-g원격 GDB를 이용하여 디버깅할 때에는 kldstat 명령을 타겟 시스템에서 실행시켜 모듈이 로딩된 곳을 찾을 수 있습니다.
# kldstat
Id Refs Address Size Name
1 4 0xc0100000 1c1678 kernel
2 1 0xc0a9e000 6000 linprocfs.ko
3 1 0xc0ad7000 2000 warp_saver.ko
4 1 0xc0adc000 11000 linux.ko만약 충돌 덤프를 디버깅할 때에는 linker_files 리스트를 따라서 가야 합니다. 이 리스트는 linker_files->tqh_first에서 시작하며, 찾는 filename을 가지는 엔트리를 찾을 때까지 link.tqe_next 포인터를 따라 진행합니다. 찾은 엔트리의 address 멤버가 해당 모듈의 로딩된 주소입니다.
다음으로는 모듈 내에서의 텍스트 섹션의 옵셋을 찾아내야 합니다.
# objdump --section-headers /sys/modules/linux/linux.ko | grep text
3 .rel.text 000016e0 000038e0 000038e0 000038e0 2**2
10 .text 00007f34 000062d0 000062d0 000062d0 2**2위의 예제에서 찾아야 하는 것은 .text 섹션이며, 섹션 10이 됩니다. 네번째 숫자 영역(전체적으로는 여섯번째 영역)은 파일 내의 텍스트 섹션의 옵셋을 16진수로 나타낸 것입니다. 이 값을 kldstat에 의해 알아낸 로딩 주소에 더해 해당 모듈의 메모리 상에서의 텍스트 주소를 구합니다.
(kldstat에 의해 얻어낸)모듈의 로딩 주소를 취하여 여기에 모듈 내에서의 텍스트 섹션의 옵셋 값을 더합니다(예제에서는 0x62d0 + 0xc0adc000 = c0ae22d0). 이 값이 모듈 코드가 재배치된 주소가 됩니다. GDB의 add-symbol-file 명령을 이용하여 모듈에 대한 정보를 디버거에 알려줍니다.
(kgdb) add-symbol-file /sys/modules/linux/linux.ko 0xc0ae22d0
add symbol table from file "/sys/modules/linux/linux.ko" at text_addr = 0xc0ae22d0?
(y or n) y
Reading symbols from /sys/modules/linux/linux.ko...done.
(kgdb)이제 모듈 내의 모든 심볼에 대해 억세스를 할 수 있게 됩니다.