주요 리눅스 커널 디버깅 기법

EEEFFEE·2023년 11월 22일
0

Linux 환경

목록 보기
5/9

23.11.22 최초 작성
23.11.24 crash utility 추가
23.11.28 ftrace message 추가

1. printk

  • printf와 같은 커널 출력 함수
  • 에러 상황에서 kernel 로그를 출력 / 중요 동작을 출력하는 데 사용
  • 상태를 보고자 하는 커널에 printk 추가
  • 자주 호출되면 전체적인 성능 저하

#include <linux/module.h>
#include <linux/kernel.h>

int init_module(void){
	printk(KERN_INFO "Hello world 1.\n");
    return 0;
}

void cleanup_module(void){
	printk(KERN_INFO "Goodbye world 1.\n);
}

1.1 로그 레벨

  • 설정된 레벨에 따라 printk에 의해 출력하는 범위가 달라짐
    (낮음/적음높음/많음)
  • Default log level : KERN_WARNING

#define KERN_EMERG "<0>" /* system is unusable */
#define KERN_ALERT "<1>" /* action must be taken immediately */
#define KERN_CRIT "<2>" /* critical conditions */
#define KERN_ERR "<3>" /* error conditions */
#define KERN_WARNING "<4>" /* warning conditions */
#define KERN_NOTICE "<5>" /* normal but significant condition */
#define KERN_INFO "<6>" /* informational */
#define KERN_DEBUG "<7>" /* debug-level messages */

echo 7 > /proc/sys/kernel/printk		//로그레벨 설정

cat /proc/sys/kernel/printk
>7	 4	 1	 3
//current, default, minimum, boot-time-default

dmesg -n 5								//터미널을 통해 로그레벨 설정

2. dump_stack

  • 스택 트레이스를 커널 로그로 출력
  • 예외 처리/심각한 오류에 사용

#include <linux/kernel.h>

dump_stack();

3. sysrq 매직 키

  • 키보드 자판의 SysRq키를 입력하면 특정 동작을 작동시킴

echo -<> > /proc/sysrq-trigger

	-s : sync 
    -u : read-only로 리마운트
    -t : 현재 태스크 출력
    -c : 커널 크래시 유발
    -b : 재부팅

4. ftrace

  • Interrupt, Scheduling, Workqueue와 같은 커널의 세부 동작 트레이싱
  • 필터로 지정한 함수의 콜 스택, Context, CPU 번호, 프로세스 정보확인 가능
  • printk에 비해 오버헤드가 적은 편

4.1 ftrace 설정

  1. 커널 설정 config 활성화
CONFIG_FTRACE=y
CONFIG_DYNAMIC_FTRACE=y
CONFIG_FUNCTION_TRACER=y
CONFIG_FUNCTION_GRAPH_TRACER=y
CONFIG_IRQSOFF_TRACER=y
CONFIG_SCHED_TRACER=y
CONFIG_FUNCTION_PROFILER=y
  1. set_ftrace_filter에서 트레이싱 하려는 함수 이름 지정 (function, function_graph일 경우만 지정)

    • 지정하지 않을 시 모든 함수 트레이싱
    • avaiable_filter_functions파일에 포함된 함수만 지정 가능
echo schedule > /sys/kernel/debug/tracing/set_ftrace_filter
  1. tracing_on 활성화
echo 0 > /sys/kernel/debug/tracing/tracing_on		//비활성화

													//함수 지정
echo 1 > /sys/kernel/debug/tracing/events/irq/irq_handler_exit/enable

echo 1 > /sys/kernel/debug/tracing/tracing_on		//활성화

4.2 ftrace 종류

  1. nop : ftrace 이벤트만 출력
  2. function : set_ftrace_filter로 지정한 함수를 누가 호출했는지 출력
  3. function_graph : 함수 실행 시간과 세부 호출 정보를 그래프 모맷으로 출력

4.2 message 분석

kworker/u8:2-122   [000] d.h.  16248.689423: irq_handler_entry: irq=86 name=mmc1
kworker/u8:2-122   [000] d.h.  16248.689511: irq_handler_exit: irq=86 ret=handled
  • kworker/u8:2-122 : pid가 122인 kworker/u8:2가 실행하는 중 인터럽트 발생
  • [000] d.h. : 0번 cpu의 컨텍스트 정보로 각각 다음과 같은 정보를 나타냄
    • d : cpu의 인터럽트를 비활성화한 상태
    • n : 현재 프로세스가 선점 스케줄링 될 수 있는 상태
      - h / s : h이면 인터럽트 컨텍스트, s면 Soft IRQ 컨텍스트
    • 프로세스의 thread_info 구조체의 preempt_cout 값
  • 16248.689423 ~ 16248.689511 : 인터럽트가 16248.689423초에 시작해 16248.689511초에 끝남
  • irq=86 : 86번 인터럽트 핸들러 실행

5. crash utility

  • 리눅스 커널을 gdb로 디버깅할 수 있는 프로그램

5.1 설치


sudo apt install linux-crashdump
sudo apt install kexec-tools
sudo apt install linux-crashdump
sudo apt install kdump-tools

crash -v

5.2 실행


$crash								//crash 모드 진입
crash> help							//명령어 확인
crash> log -m						//커널 로그 확인
crash> ps							//실행중인 프로세스 상태 출력
crash> bt							//실행중인 프로세스 정보 출력

crash> task							//(실행중인) 프로세스관련 구조체 정보 확인
crash> vm							//(실행중인) 프로세스관련 구조체의 메모리 정보 확인
crash> kmem							//(실행중인) 커널 메모리와 관련된 정보 출력

crash> task							//실행중인 프로세스관련 구조체 정보 확인
crash> sym							//커널의 심볼 정보 출력

0개의 댓글

관련 채용 정보