카테고리

asm (27) bootloader_x86_grub (1) C (92) compile (11) config (76) CPP (13) CSS (1) debugging (7) gimp (1) Go (1) html (1) Java (1) JavaScript (1) kernel (19) LibreOffice (3) Linux system progamming (21) MFC (1) opencv (4) OpenGL (1) PHP (1) Python (4) qemu (29) shell (3) socket (7) troubleshooting (2) ubuntu18.04 (2) windows (1)

2019/01/12

vmware 가상 머신을 사용 커널 디버깅 환경 구축

vmware 가상 머신을 사용 디버깅.
커널을 가상 직렬 포트를 통해 디버그 진행.

가상 시리얼 포트 설정
vmware 설정 파일 vmx 파일을 열어 다음을 추가

serial1.present = "TRUE"
serial1.yieldOnMsrRead = "TRUE"
serial1.fileType = "pipe"
serial1.fileName = "/tmp/com_ubuntu1510" ---> 현재 1510 을 사용

ttyS0 또는 ttyS1?
다른 가상 하드웨어가 있을 수 있음.(ttyS0).

호스트 설정
터미널을 열고 소켓으로 리다이렉션 명령어 입력.
socat -d -d /tmp/com_ubuntu1510 tcp-listen:9999

새로운 터미널을 열고 텔넷으로 접근
telnet 127.0.0.1 9999

명령어 전달 테스트
echo whatever > /dev/ttyS0

텔넷 접속 콘솔에 whatever 표시 확인. 만약 메세지가 전달이 안될 경우 ttyS1로 변경해 다시 시도.

게스트:KGDB 설치
리눅스 커널이 KGDB를 지원하는 확인.

$ grep KGDB /boot/config-$(uname -r)
CONFIG_SERIAL_KGDB_NMI=y
CONFIG_HAVE_ARCH_KGDB=y
CONFIG_KGDB=y                         <---
CONFIG_KGDB_SERIAL_CONSOLE=y          <---
# CONFIG_KGDB_TESTS is not set
CONFIG_KGDB_LOW_LEVEL_TRAP=y
CONFIG_KGDB_KDB=y

커널 확인 후 커널 커맨드 라인 kgdboc=ttyS0,115200 kgdbwait 추가

커널 명령어 인자 확인 : https://www.kernel.org/doc/Documentation/kernel-parameters.txt
kgdboc=ttyS0,115200 - 콘솔, 시리얼 포트 ttyS0 및 전송 속도 1152000 kgdb 설정
kgdbwait - 기본 커널 중지 후 커널 디버그 모드로 시작


부트로더 설정
/etc/grub.d/40-custom

# /etc/grub.d/40-custom, copied from /boot/grub/grub.cfg
menuentry 'UbuntuKGDB' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-simple-4492a93c-91e2-4979-b5b9-71e32901511c' {
insmod gzio
insmod part_msdos
insmod ext2
set root='hd0,msdos1'
search --no-floppy --fs-uuid --set=root 4492a93c-91e2-4979-b5b9-71e32901511c
linux /boot/vmlinuz-4.2.0-14-generic root=UUID=4492a93c-91e2-4979-b5b9-71e32901511c ro find_preseed=/preseed.cfg auto noprompt priority=critical locale=en_US kgdboc=ttyS0,115200 kgdbwait
initrd /boot/initrd.img-4.2.0-14-generic
}

/etc/default/grub
2줄 주석 처리
#GRUB_HIDDEN_TIMEOUT=10
#GRUB_HIDDEN_TIMEOUT_QUIET=false

grub 적용
update-grub

디버깅할 커널 항목으로 재부팅 후 kgdb 연결 대기 상태 환경 구성.

호스트
sysrq 디버거 사용 비활성화

echo 0 > /proc/sys/kernel/sysrq
# Or with command,
# sysctl kernel.sysrq = 0
# And to survive reboot,
# echo 'kernel.sysrq = 0' >> /etc/sysctl.conf

게스트 활성화
echo 1 > /proc/sys/kernel/sysrq

커널 브레이크 포인터 지정 및 추적
커널 디버그 정보 확인 https://nautiluslee.blogspot.com/2019/01/blog-post_12.html
gdb debuginfo/usr/lib/debug/boot/vmlinux-4.2.0-14-generic
(gdb) set substitute-path /build/linux-xyuzCP/linux-4.2.0 /home/hfu/debuginfo/linux-source-4.2.0/linux-source-4.2.0
(gdb) target remote localhost:9999
(gdb) c

게스트
디버그 진입
# press Alt+SysRq+g
# OR
echo g > /proc/sysreq-trigger


커널 모듈 디버그
gcc 옵션 중 -g 를 사용해 빌드 후 로드 modprobe vmhgfs

_dir=/sys/module/vmhgfs/sections
cmd="add-symbol-file ~/vmhgfs.ko $(cat $_dir/.text) -s .bss $(cat $_dir/.bss) -s .data $(cat $_dir/.data)"
echo "$cmd" > add_vmhgfs_symbol.gdb

심볼 파일 로드 gdb 스크립트 호스트 복사 디버그 시작
(gdb) source add_vmhgfs_symbol.gdb
(gdb) break HgfsSendRequest

추가 정보
1. module_init 디버깅 방법
이 부분을 확인 하다 보면 jtga 디버거도 결국 vmware workstation 솔루션을 사용.

2. sysRq
실행중인 커널 사용해 디버거로 분석.

리눅스 배포판 커널 디버그정보 패키지 검색 방법.

리눅스 배포판 커널 디버그정보 패키지 검색 방법.

리눅스 코어 분석은 해당 커널의 디버그정보 패키지를 찾는 것이다. 메모리에서 커널 버전을 추출 할 때 첫 번째 해야 할 일은 커널 릴리스 하는 것이며, 소스 및 심볼 정보가 있는 디버그 패키지를 찾는게 가장 먼저 선행 되어야 하기 때문에 디버깅 정보가 담긴 패키지를 찾는다.

요즘 가장 많이 사용되는 배포한 ubuntu, RHEL, SLES에 대한 패키지를 찾는 방법을 정리 해 놓는다.

우분투 릴리즈 목록: https://wiki.ubuntu.com/Releases
우분투 릴리즈 및 커널 버전 목록: https://en.wikipedia.org/wiki/Ubuntu_version_history#Table_of_versions
디버깅 정보 저장소: http://ddebs.ubuntu.com/pool/main/l/linux/

패키지 이름
kernel: linux-image
symbol: linux-image-*-dbgsym
source: linux-source

패키지 추출 명령어.
ar -x linux-image-3.2.0-41-generic-dbgsym_3.2.0-41.66_amd64.ddeb

데비안
디버깅 정보 추가
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=365349
예: https://packages.debian.org/jessie/linux-image-3.16.0-4-amd64-dbg

레드햇

레드햇 엔터프라이즈 릴리자 정버: https://access.redhat.com/articles/3078
CentOS 디버그 패키지는 Redhat과 호환
패키지 저장소: http://vault.centos.org/
디버깅 저장소: http://debuginfo.centos.org/

패키지 이름
kernel: kernel
source: kernel-debuginfo-common
symbol: kernel-debuginfo

패키지 추출
rpm2cpio kernel-2.6.32-573.el6.x86_64.rpm | cpio -idmv

오라클 UEK(Unbreakable Enterprise kernel)

패키지 저장소 : http://public-yum.oracle.com/repo/OracleLinux/ ---> 저장소가 자꾸 변경됨, 구글 검색
디버깅 저장소 : https://oss.oracle.com/ol6/debuginfo/

CentOS 추가 리소스_정장소_디버그정보: https://wiki.centos.org/AdditionalResources/Repositories/DebugInfo
페도라 패키징 디버그 정보: https://fedoraproject.org/wiki/Packaging:Debuginfo

SLES 커널 릴리즈: https://wiki.microfocus.com/index.php/Kernel_versions
SLES 디버깅 정보: https://www.novell.com/support/#3074997

zypper search -s 'kernel-default'
zypper install --download-only --oldpackage kernel-default-debuginfo-3.0.101-0.15.1
# debuginfo package needs the kernel binary in SLES
zypper install --download-only --oldpackage kernel-default-base-3.0.101-0.15.1
# find the rpm in /var/cache/zypp/packages

SLES 저장소를 찾지 못한 상태.