Arm Linux Kernel Hacks

rousalome.egloos.com

포토로그 Kernel Crash


통계 위젯 (화이트)

37120
1703
402252


[리눅스커널] 커널 디버깅과 코드 학습: 부팅 과정에서 ftrace는 어떻게 볼까? 3. 커널 디버깅과 코드 학습

ftrace는 기본으로 부팅 후 ftrace 로그를 저장하지 않습니다. 부팅 후 ftrace는 비활성화되는 것입니다. 따라서 부팅이 끝난 후 다음 같은 echo 명령어로 설정해야 ftrace 로그를 킬 수 있습니다.

echo 1 > /sys/kernel/debug/tracing/tracing_on

그런데 가끔 부팅 도중 ftrace 로그를 보고 싶을 때가 있습니다.

부팅 과정에서 어떤 프로세스가 실행됐는지 알고 싶을 때
프로세스 실행과 종료 과정을 보고 싶을 때

다음에 소개하는 패치 코드를 라즈베리파이에 적용하면 라즈비안이 부팅할 때 ftrace 로그를 활성화하면서 ftrace 로그를 저장합니다.

먼저 전체 소스 코드를 소개합니다.

diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig
index 4ad6f6c..2789562 100644
--- a/kernel/trace/Kconfig
+++ b/kernel/trace/Kconfig
@@ -702,6 +702,12 @@ config TRACING_EVENTS_GPIO
        help
          Enable tracing events for gpio subsystem

+config ENABLE_FTRACE_BOOT
+     bool "Enable ftrace at boot"
+        depends on TRACING
+        help
+          Enable ftrace at boot
+
 endif # FTRACE

 endif # TRACING_SUPPORT
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
index d53268a..db17a5a 100644
--- a/kernel/trace/trace_events.c
+++ b/kernel/trace/trace_events.c
@@ -3110,6 +3110,47 @@ static __init int event_trace_enable(void)
        return 0;
 }

+#ifdef CONFIG_ENABLE_FTRACE_BOOT
+static void ftrace_events_enable(int enable)
+{
+       if (enable) {
+               trace_set_clr_event(NULL, "printk", 1);
+               trace_set_clr_event(NULL, "console", 1);
+               trace_set_clr_event(NULL, "signal_generate", 1);
+               trace_set_clr_event(NULL, "signal_deliver", 1);
+               trace_set_clr_event(NULL, "sched_switch", 1);
+       } else {
+               tracing_off();
+               trace_set_clr_event(NULL, NULL, 0);
+       }
+}
+
+static __init int rpi_enable_ftrace_boot(void)
+{
+       struct trace_array *tr;
+       int ret = 0;
+
+       tr = top_trace_array();
+       if (!tr) {
+               pr_err("%s: Invalid tr from top_trace_array n", __func__);
+               return -ENODEV;
+       }
+
+       ret = tracing_update_buffers();
+       if (ret != 0) {
+               pr_err("%s: invalid buffer ret=%dn", __func__, ret);
+               return -ENODEV;
+       }
+
+       ftrace_events_enable(1);
+       set_tracer_flag(tr, TRACE_ITER_OVERWRITE, 0);
+
+       tracing_on();
+
+       return 0;
+}
+
+late_initcall(rpi_enable_ftrace_boot);
+#endif

위 패치 코드의 핵심은 다음 코드 조각입니다.
+static void ftrace_events_enable(int enable)
+{
+       if (enable) {
+               trace_set_clr_event(NULL, "signal_generate", 1);
+               trace_set_clr_event(NULL, "signal_deliver", 1);
+               trace_set_clr_event(NULL, "sched_switch", 1);
+       } else {
+               tracing_off();
+               trace_set_clr_event(NULL, NULL, 0);
+       }
+}

trace_set_clr_event() 함수 2 번째 인자로 ftrace 이벤트를 설정합니다. 위 코드는 다음 이벤트를 설정합니다.
signal_generate
signal_deliver
sched_switch

세부 패치 코드 분석은 아쉽지만 이 책의 범위를 넘어서는 것 같으니, ftrace_events_enable() 함수 내 trace_set_clr_event() 함수를 써서 ftrace 이벤트를 설정한다는 정도로 기억합시다.

* 유튜브 강의 동영상도 있으니 같이 들으시면 더 많은 걸 배울 수 있습니다. 





"혹시 궁금한 점이 있으면 댓글로 질문 남겨주세요. 아는 한 성실히 답변 올려드리겠습니다!" 

Thanks,
Austin Kim(austindh.kim@gmail.com)

커널 디버깅과 코드 학습

디버깅이란
ftrace
   * ftrace란     


# Reference: For more information on 'Linux Kernel';

디버깅을 통해 배우는 리눅스 커널의 구조와 원리. 1

디버깅을 통해 배우는 리눅스 커널의 구조와 원리. 2


Thanks,
Austin Kim



핑백

덧글

댓글 입력 영역