[Linux][Kernel] ftrace: function/stack tracer 설정하기

AustinKim의 이미지

리눅스 커널에서 제공하는 여러 profile tool 중에 ftrace가 있어요. 매우 강력해요.
잠깐 기억하는게, 저번 리눅스 커널 세미나에 갔었을 때 리눅스 커널 고수들이 ftrace로 벌이는 향연을 보고 참 라이브 공연에 있는 듯한 착각을 받았어요. ftrace 기능 중 stack tracer 기능을 잠깐 소개하고자 해요.

리눅스 커널 고수들 ftrace 로그를 밥 먹듯이 본다고 하네요. 저도 밥 먹듯이 보고는 있지만, 영 실력이 느는 것 같지 않아 짜증이 나지만요. 우선 stack tracer 기능을 좀 소개하려고 해요. 기능도 참 강력해요.

아래와 같이 커널 Config를 설정한 다음 리눅스 커널을 빌드한 다음 쓰고 있는 리눅스 시스템에 적용(다운로드)하면 됩니다.

--- a/arch/arm/configs/pompeii_com_defconfig
+++ b/arch/arm/configs/pompeii_com_defconfig
@@ -778,6 +777,14 @@ CONFIG_DEBUG_SET_MODULE_RONX=y
 CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y
 CONFIG_SECURITY=y
 CONFIG_SECURITY_NETWORK=y
+CONFIG_DYNAMIC_FTRACE=y
+CONFIG_FUNCTION_TRACER=y
+CONFIG_FUNCTION_GRAPH_TRACER=y
+CONFIG_IRQSOFF_TRACER=y
+CONFIG_SCHED_TRACER=y
+CONFIG_BLK_DEV_IO_TRACER=y
+CONFIG_FUNCTION_PROFILER=y
+CONFIG_STACK_TRACER=y
+CONFIG_TRACER_SNAPSHOT=y
 CONFIG_LSM_MMAP_MIN_ADDR=4096
 CONFIG_HARDENED_USERCOPY=y
 CONFIG_SECURITY_SELINUX=y


컴파일 후 아래 available_tracers를 확인하면 끝이죠.
cat /sys/kernel/debug/tracing/available_tracers
 
blk function_graph wakeup_dl wakeup_rt wakeup irqsoff function nop

자, 이제 ftrace를 설정해볼까요?
__insert_vmap_area 함수가 어떤 콜스택으로 호출되는지 알고 싶거든요.

/d/tracing/buffer_size_kb ftrace 버퍼 사이즈 좀 늘려주시고,
d/tracing/set_ftrace_filter에 __insert_vmap_area 추가하고,
d/tracing/options/func_stack_trace을 1로 설정하면 끝이죠.

 
adb shell "echo  > d/tracing/set_event"
adb shell "sleep 1"
 
adb shell "echo 0 > d/tracing/tracing_on"
adb shell "sleep 1"
 
adb shell " echo 50000 > /d/tracing/buffer_size_kb"
 
adb shell "echo function > d/tracing/current_tracer"
adb shell "sleep 1"
 
adb shell "echo 1 > /d/tracing/events/sched/sched_switch/enable"
adb shell "sleep 1"
 
adb shell "echo __insert_vmap_area  > d/tracing/set_ftrace_filter"
adb shell "sleep 1"
 
adb shell "echo 1 > d/tracing/options/func_stack_trace"
adb shell "sleep 1"
 
adb shell "echo 1 > d/tracing/tracing_on"
adb shell "sleep 1"

adb shell 명령어가 붙은 것은 안드로이드 디바이스에서 테스트를 했기 때문입니다.
쓰고 있는 리눅스 시스템에 따라 adb shell은 사용 안해도 상관은 없습니다.

여기서 중요한 건 ftrace를 설정할 때 잠깐 d/tracing/tracing_on을 0으로
세팅하여 주시고, 각각 ftrace 설정 시 sleep을 줄 필요가 있어요.

왜냐면, ftrace 옵션을 다 설정하고 ftrace가 돌면 시스템 과부하로 시스템이 와치독 리셋으로 죽어버리는 수가 있거든요.
아래 리눅스 커널 커뮤니티에서도 업데이트한 로그가 있는데요.
https://lkml.org/lkml/2017/8/6/153

위 메일링 리스트에서 논의한 내용은, (기억이 가물 가물 하네요)
ftrace를 graph_tracer로 설정하면 엄청난 ftrace 로그가 찍히는데, Daniel Lezcano이 분은 CPU clock을 높혔더니 stall현상이 안 나왔다는 군요.

아무튼 다른 개발자들도 위 설정으로 ftrace을 키면 다른 사이드 이팩트는 없다고 동의했어요.(다른 메일이 날라왔죠.)

자, 그럼 위와 같이 설정하고, 5분 후, d/tracing/tracing_on을 0으로 다시 바꿔서 ftrace를 동작을 잠깐 멈추고,
"d/tracing/trace" 로그를 보면 아래 정보를 볼 수 있어요.

            adbd-5414  [000] ...2   246.224086: __insert_vmap_area <-alloc_vmap_area
            adbd-5414  [000] ...2   246.224118: <stack trace>
 => __insert_vmap_area
 => alloc_vmap_area
 => __get_vm_area_node
 => __vmalloc_node_range
 => __vmalloc_node
 => vmalloc
 => n_tty_open
 => tty_ldisc_open
 => tty_ldisc_hangup
 => __tty_hangup
 => tty_vhangup
 => pty_close
 => tty_release
 => __fput
 => ____fput
 => task_work_run
 => do_work_pending
 => work_pending
// ...생략...
 
            adbd-5414  [000] ...2   247.567047: __insert_vmap_area <-alloc_vmap_area
            adbd-5414  [000] ...2   247.567071: <stack trace>
 => __insert_vmap_area
 => alloc_vmap_area
 => __get_vm_area_node
 => __vmalloc_node_range
 => __vmalloc_node
 => vmalloc
 => n_tty_open
 => tty_ldisc_open
 => tty_ldisc_hangup
 => __tty_hangup
 => tty_vhangup
 => pty_close
 => tty_release
 => __fput
 => ____fput
 => task_work_run
 => do_work_pending
 => work_pending
// ... 생략...
           <...>-5568  [002] ...2   247.572389: __insert_vmap_area <-alloc_vmap_area
           <...>-5568  [002] ...2   247.572407: <stack trace>
 => __insert_vmap_area
 => alloc_vmap_area
 => __get_vm_area_node
 => get_vm_area
 => binder_alloc_mmap_handler
 => binder_mmap
 => mmap_region
 => do_mmap_pgoff
 => vm_mmap_pgoff
 => SyS_mmap_pgoff
 => ret_fast_syscall

이 방식으로 커널 코드를 디버깅하면 함수 콜스택을 손 쉽게 확인할 수 있습니다.

(Personal Blog)
http://rousalome.egloos.com

Forums: 

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.