Linux Ftrace
해당 포스트에서는 기본적인 ftrace 사용법에 대하여 설명합니다.
ftrace는 커널 내부 동작을 파악하기 위하여 사용하는 디버깅 도구입니다.
다음과 같은 기능들이 있습니다.
- dynamic kernel function tracing
- event tracing
- latency tracing
- stack tracing
- function profiling
사용법은 /sys/kernel/debug/tracing 아래에 특정 값들을 써서 사용합니다.
/sys/kernel/debug/tracing/set_ftrace_filter에 특정 커널 함수를 쓰면 해당 함수만 필터링하여 트레이싱합니다.
/sys/kernel/debug/tracing/current_tracer에 function을 쓰면 기본적인 function 트레이싱을 하고, function_graph를 쓰면 그래프 형태로 function 트레이싱을 합니다.
물론 사용법을 하나하나 익히는 것이 ftrace라는 툴을 이해하기는 가장 좋겠지만, 사용은 간편하게 다음과 같은 스크립트를 사용할 수 있습니다. (원본은 Austin Kim님의 스크립트입니다.)
trace_ftrace.sh
#!/bin/bash
echo 0 > /sys/kernel/debug/tracing/tracing_on
sleep 1
echo "tracing_off"
echo 0 > /sys/kernel/debug/tracing/events/enable
sleep 1
echo "events diabled"
echo do_one_initcall > /sys/kernel/debug/tracing/set_ftrace_filter
sleep 1
echo "set_ftrace_filter init"
echo function > /sys/kernel/debug/tracing/current_tracer
sleep 1
echo "function tracer enabled"
echo kmem_cache_alloc_trace __slab_alloc > /sys/kernel/debug/tracing/set_ftrace_filter
sleep 1
echo "set_ftrace_filter enabled"
echo 1 > /sys/kernel/debug/tracing/events/kmem/kmalloc/enable
echo 1 > /sys/kernel/debug/tracing/events/kmem/kfree/enable
sleep 1
echo "event enabled"
echo 1 > /sys/kernel/debug/tracing/options/func_stack_trace
echo "function stack trace enabled"
echo 1 > /sys/kernel/debug/tracing/tracing_on
echo "tracing_on"
ftrace 설정을 하는 스크립트입니다.
네 번째 단락에서 current_tracer에 function과 function_graph 중 선택하여 트레이싱 방식을 정할 수 있습니다.
다섯 번째 단락에서 kmem_cache_alloc_trace와 __slab_alloc과 같이 트레이싱하려는 커널 함수를 입력할 수 있습니다.
물론 모든 커널 함수를 트레이싱 할 수 있는 것은 아닙니다. inline 함수와 같이 커널 심볼 테이블에 없는 함수는 트레이싱 할 수 없습니다. 해당 상황에서는 해당 함수가 커널 심볼 테이블에 들어갈 수 있도록 커널을 수정하여 재설치하면 트레이싱 할 수 있습니다.
현재 커널에서 트레이싱할 수 있는 함수 목록은 /sys/kernel/debug/tracing/available_filter_functions 파일에서 찾을 수 있습니다.
여섯 번째 단락에서는 트레이싱하고자 하는 이벤트들을 설정합니다.
마찬가지로 트레이싱할 수 있는 이벤트 목록은 /sys/kernel/debug/tracing/available_events 파일에서 찾을 수는 있습니다만, 어차피 이벤트에 해당하는 디렉토리를 찾아서 enable 파일에 0(비활성화)/1(활성화) 값을 쓰는 것이긴 합니다.
get_ftrace.sh
#!/bin/bash
echo 0 > /sys/kernel/debug/tracing/tracing_on
echo "ftrace off"
sleep 3
cp /sys/kernel/debug/tracing/trace .
mv trace ftrace.log
ftrace 결과를 파일로 출력해주는 스크립트입니다.
3초간 트레이싱한 결과를 ftrace.log 파일로 출력합니다.
sleep 3의 숫자를 바꾸면 원하는 시간만큼 트레이싱을 할 수 있습니다.
trace_printk
ftrace는 trace_printk라는 함수를 통해 원하는 내용을 더욱 유연하게 트레이싱 할 수 있게 해줍니다.
위의 내용들은 고정된 형식으로만 트레이싱 하지만, 이 함수를 커널 소스 원하는 곳에 추가함으로써 추가 메시지를 얻을 수 있습니다.
사용법은 printk 함수와 똑같습니다.
trace_printk("data len : %d\n", skb->data_len);
위와 같은 라인을 커널의 원하는 소스 코드에 추가하고, 해당 소스 파일에 linux/kernel.h 헤더 파일을 추가함으로써 원하는 값 등을 트레이싱 시 확인할 수 있습니다.