코어 덤프에서 wakelock 정보를 CrashTool(red hat crash-utility)로 확인할 수 있는 팁을 공유하고자 해요.
CrashTool "rbtree"에 대해 강력한 명령어를 제공하거든요.
wakelocks_tree란 전역 변수에서 rb_node를 확인하고요. 0xffffffc0e397b108
아래 오프셋으로 명령어를 주면 되요.
crash64> tree -t rbtree -o wakelock.node -N 0xffffffc0e397b108
ffffffc0e397b100
ffffffc0d4262200
ffffffc0c9e8e100
ffffffc066355400
ffffffc06a0a0900
ffffffc0c5cd8600
ffffffc04fddcb00
ffffffc0e397bb00
ffffffc06c55b800
ffffffc06c7c3e00
ffffffc0eb6b5100
ffffffc0d6dc2b00
ffffffc06a124500
ffffffc0c5d35300
(where)
crash64> p wakelocks_tree
wakelocks_tree = $1 = {
rb_node = 0xffffffc0e397b108
}
자 하나 하나 씩 점검 좀 해볼께요.
"PowerManagerService.Display" wakelock 소스는 active가 true이니 wakelock을 잡고 있네요.
crash64> struct wakelock ffffffc0d4262200
struct wakelock {
name = 0xffffffc063479080 "PowerManagerService.Display",
node = {
__rb_parent_color = 18446743802650013961,
rb_right = 0xffffffc0c5cd8608,
rb_left = 0xffffffc0c9e8e108
},
// .. 생략...
expire_count = 0,
wakeup_count = 14,
pending_count = 6,
active = true,
autosleep_enabled = false
"KeyEvents"는 안 잡고 있고요.
crash64> struct wakelock ffffffc0c9e8e100
struct wakelock {
name = 0xffffffc066213900 "KeyEvents",
node = {
__rb_parent_color = 18446743802390913545,
rb_right = 0xffffffc06a0a0908,
rb_left = 0xffffffc066355408
},
// .. 생략...
wakeup_count = 258,
pending_count = 1,
active = false,
autosleep_enabled = false
이런 식으로 wakelock을 누가 잡고 있는 지 확인할 수 있어요.
그럼 wakelock을 잡는 코드는 어디일까요? 아래 패치를 잠깐 보면 알 수 있어요.
diff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c
index 7af116e..18b8b2e 100644
--- a/drivers/base/power/wakeup.c
+++ b/drivers/base/power/wakeup.c
@@ -177,6 +177,9 @@ void wakeup_source_add(struct wakeup_source *ws)
return;
spin_lock_init(&ws->lock);
+
+ trace_printk("+ wakelock add - process(%s), from(%pF)\n", current->comm, __builtin_return_address(0));
+
setup_timer(&ws->timer, pm_wakeup_timer_fn, (unsigned long)ws);
ws->active = false;
ws->last_time = ktime_get();
@@ -547,6 +550,8 @@ static void wakeup_source_activate(struct wakeup_source *ws)
/* Increment the counter of events in progress. */
cec = atomic_inc_return(&combined_event_count);
+ trace_printk("+ wakelock activate process(%s), from(%pF)\n", current->comm, __builtin_return_address(0));
+
trace_wakeup_source_activate(ws->name, cec);
}
위 패치를 적용하고 나면 아래 ftrace log로 언제 wakelock을 잡았는 지 확인할 수 있어요
<...>-4480 [000] .... 32.668732: wakeup_source_activate: + wakelock activate process(rild), from(pm_wake_lock+0xa4/0x174) source[radio-interface]
상세 wakelock 동작에 대해서는 나중에 다뤄보도록 할께요.
'[Debugging] Tips' 카테고리의 다른 글
커널 오브젝트 Kernel Object - rbtree debugging(parent directory) - (2) (0) | 2023.05.04 |
---|---|
IPI (Inter Processor Interrupts) 소개 및 디버깅 패치 (1) (0) | 2023.05.04 |
crash-utility(crash tool) - ps command (0) | 2023.05.04 |
crash-utility(crashtool) - 리다이렉션 커맨드 (0) | 2023.05.04 |
crash-utility(crashtool) - runq awk 명령어 (0) | 2023.05.04 |