[리눅스커널][디버깅] 유저공간 abort 발생 시 커널 패닉 유발하는 패치

AustinKim의 이미지

개발 도중에 유저 공간에서 abort가 발생합니다. 안드로이드 플렛폼에서는 tombstone이 생성돼 레지스터와 콜스택을 확인할 수 있습니다.

 
Revision: '0'
ABI: 'arm'
pid: 16458, tid: 16513, name: thermal-engine  >>> /system/vendor/bin/thermal-engine <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0
Cause: null pointer dereference
    r0 00000000  r1 a73a48c0  r2 8362dec4  r3 8362deec
    r4 80000000  r5 00000000  r6 83639000  r7 83c35fd8
    r8 00000000  r9 00000000  sl 000084d0  fp a73c2500
    ip 80808000  sp a40885b0  lr 83617861  pc 8362ddae  cpsr 80070030
    d0  5f7a745f736e6520  d1  7269762f7365636d
    d2  6568742f6c617543  d3  6568742f6c616d0a


하지만 가끔 유저 공간에서 abort가 발생했을 때 커널 패닉을 유발해 전체 콜스택을 보고 싶을 때가 있습니다.
이번 시간에 이를 위한 설정 방법을 살펴보겠습니다.

코드 수정

먼저 커널 컨피그를 수정합시다.

 
diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig
index c4e6527..5452f34 100644
--- a/arch/arm/configs/bcm2709_defconfig
+++ b/arch/arm/configs/bcm2709_defconfig
@@ -808,3 +808,4 @@
 # Enable LG VPN
 CONFIG_LG_VPN_V34=y
 CONFIG_LGE_USE_DEFAULT_HARD_RESET=y
+CONFIG_DEBUG_USER=y

커널 커맨드에 user_debug=24를 전달하는 코드를 부트 로더에 추가합니다.

 
diff --git a/target/rpi_common/boot_loader_common.c b/target/rpi_common/boot_loader_common.c
index dc7b483..ff2c2bd 100644
--- a/target/rpi_common/boot_loader_common.c
+++ b/target/rpi_common/boot_loader_common.c
@@ -188,6 +188,7 @@
 	bootcmd_add_new_key("gpt");
+	bootcmd_add_pair("user_debug","24");
 }

위 코드는 LK(Little Kernel)에서 커맨드 라인을 추가하는 코드입니다.

user_debug 커널 커맨드를 24로 설정한 이유는 다음 코드에서 UDBG_SEGV와 UDBG_BUS 매크로가 아래와 같이 설정돼 있기 때문입니다.
UDBG_SEGV = 1<<3 (8)
UDBG_BUS = 1<<4(16)

 
[<a href="https://elixir.bootlin.com/linux/v4.19.30/source/arch/arm/mm/fault.c" rel="nofollow">https://elixir.bootlin.com/linux/v4.19.30/source/arch/arm/mm/fault.c</a>]
01 static void
02 __do_user_fault(struct task_struct *tsk, unsigned long addr,
03		unsigned int fsr, unsigned int sig, int code,
04		struct pt_regs *regs)
05 {
06	struct siginfo si;
07
08	if (addr > TASK_SIZE)
09		harden_branch_predictor();
10
11	clear_siginfo(&si);
12
13 #ifdef CONFIG_DEBUG_USER
14	if (((user_debug & UDBG_SEGV) && (sig == SIGSEGV)) ||
15	    ((user_debug & UDBG_BUS)  && (sig == SIGBUS))) {
16		printk(KERN_DEBUG "%s: unhandled page fault (%d) at 0x%08lx, code 0x%03x\n",
17		       tsk->comm, sig, addr, fsr);
18		show_pte(tsk->mm, addr);
19		show_regs(regs);
20	}
21 #endif

user_debug 전역 변수 기준 조건문인 14~20 번째 줄을 눈여겨봅시다.

위 두 가지 코드를 빌드한 후 타겟 디바이스에 다운로드 합시다.

테스트

다음 명령어로 print-fatal-signals 필드를 1로 설정합시다.

 
" echo 1 > /proc/sys/kernel/print-fatal-signals" 

"kill -11 4839" 명령어를 입력해 pid가 4839인 errorreporterui 프로세스를 abort 시킵니다.

커널 크래시가 발생합니다.

 
<6>[  192.145575 / 05-21 22:29:31.815][3] potentially unexpected fatal signal 11.
<6>[  192.145596 / 05-21 22:29:31.815][3] CPU: 3 PID: 4839 Comm: errorreporterui Tainted: G        W      4.19.30-gbbd0bc4-dirty #3
<6>[  192.145609 / 05-21 22:29:31.815][3] task: c244e040 ti: e1348000 task.ti: e1348000
<6>[  192.145620 / 05-21 22:29:31.815][3] PC is at 0xa6671858
<6>[  192.145630 / 05-21 22:29:31.815][3] LR is at 0xa66426dd
<6>[  192.145642 / 05-21 22:29:31.815][3] pc : [<a6671858>]    lr : [<a66426dd>]    psr: 600f0010
<6>[  192.145642 / 05-21 22:29:31.815][3] sp : bef7ddb8  ip : bef7ddc8  fp : 930eeaf0
<6>[  192.145658 / 05-21 22:29:31.815][3] r10: 00000000  r9 : 930eeb3c  r8 : 00000000
<6>[  192.145669 / 05-21 22:29:31.815][3] r7 : 0000015a  r6 : 00000000  r5 : 00000008  r4 : 00000000
<6>[  192.145680 / 05-21 22:29:31.815][3] r3 : ffffffff  r2 : 00000010  r1 : bef7de08  r0 : fffffffc
<6>[  192.145691 / 05-21 22:29:31.815][3] Flags: nZCv  IRQs on  FIQs on  Mode USER_32  ISA ARM  Segment user
<6>[  192.145702 / 05-21 22:29:31.815][3] Control: 10c0383d  Table: a134c06a  DAC: 00000051
<6>[  192.145714 / 05-21 22:29:31.815][3] CPU: 3 PID: 4839 Comm: errorreporterui Tainted: G        W      3.18.66-gbbd0bc4-dirty #3
<6>[  192.145736 / 05-21 22:29:31.815][3] [<c010e400>] (unwind_backtrace) from [<c010b4a8>] (show_stack+0x10/0x14)
<6>[  192.145752 / 05-21 22:29:31.815][3] [<c010b4a8>] (show_stack) from [<c0fd0740>] (dump_stack+0x78/0x98)
<6>[  192.145768 / 05-21 22:29:31.815][3] [<c0fd0740>] (dump_stack) from [<c01338a8>] (get_signal+0x4fc/0x5d0)
<6>[  192.145784 / 05-21 22:29:31.815][3] [<c01338a8>] (get_signal) from [<c010a878>] (do_signal+0x84/0x47c)
<6>[  192.145800 / 05-21 22:29:31.815][3] [<c010a878>] (do_signal) from [<c010ade8>] (do_work_pending+0x54/0xb4)
<6>[  192.145815 / 05-21 22:29:31.815][3] [<c010ade8>] (do_work_pending) from [<c0106bb4>] (work_pending+0xc/0x20)


다른 커널 로그입니다.
 
<7>[   72.248793 / 05-21 22:27:31.925][2] android.ui: unhandled page fault (11) at 0x00000000, code 0x005
<1>[   72.248810 / 05-21 22:27:31.925][2] pgd = da0fc000
<1>[   72.252580 / 05-21 22:27:31.925][2] [00000000] *pgd=00000000
<6>[   72.258764 / 05-21 22:27:31.935][2] CPU: 2 PID: 999 Comm: rpi.ui Tainted: G        W      4.19.30-gbbd0bc4-dirty #3
<6>[   72.258781 / 05-21 22:27:31.935][2] task: d7e0d840 ti: d7f02000 task.ti: d7f02000
<6>[   72.258793 / 05-21 22:27:31.935][2] PC is at 0x73a7c9c0
<6>[   72.258803 / 05-21 22:27:31.935][2] LR is at 0x0
<6>[   72.258814 / 05-21 22:27:31.935][2] pc : [<73a7c9c0>]    lr : [<00000000>]    psr: 00070030
<6>[   72.258814 / 05-21 22:27:31.935][2] sp : 885bc480  ip : 00000000  fp : 131e3218
<6>[   72.258830 / 05-21 22:27:31.935][2] r10: 71488688  r9 : 92778200  r8 : 00000000
<6>[   72.258840 / 05-21 22:27:31.935][2] r7 : 131e2bf0  r6 : 00000000  r5 : 00000001  r4 : 00263c64
<6>[   72.258851 / 05-21 22:27:31.935][2] r3 : 131e3218  r2 : 71488688  r1 : 00000000  r0 : 71488688
<6>[   72.258863 / 05-21 22:27:31.935][2] Flags: nzcv  IRQs on  FIQs on  Mode USER_32  ISA Thumb  Segment user
<6>[   72.258873 / 05-21 22:27:31.935][2] Control: 10c0383d  Table: 9a0fc06a  DAC: 00000051
<6>[   72.258885 / 05-21 22:27:31.935][2] CPU: 2 PID: 999 Comm: rpi.ui Tainted: G        W      3.18.66-gbbd0bc4-dirty #3
<6>[   72.258907 / 05-21 22:27:31.935][2] [<c010e400>] (unwind_backtrace) from [<c010b4a8>] (show_stack+0x10/0x14)
<6>[   72.258924 / 05-21 22:27:31.935][2] [<c010b4a8>] (show_stack) from [<c0fd0740>] (dump_stack+0x78/0x98)
<6>[   72.258940 / 05-21 22:27:31.935][2] [<c0fd0740>] (dump_stack) from [<c0115f8c>] (__do_user_fault+0x108/0x19c)
<6>[   72.258957 / 05-21 22:27:31.935][2] [<c0115f8c>] (__do_user_fault) from [<c0fe05b8>] (do_page_fault+0x33c/0x3e8)
<6>[   72.258972 / 05-21 22:27:31.935][2] [<c0fe05b8>] (do_page_fault) from [<c0100404>] (do_DataAbort+0x34/0x184)
<6>[   72.258986 / 05-21 22:27:31.935][2] [<c0100404>] (do_DataAbort) from [<c0fdec3c>] (__dabt_usr+0x3c/0x40)
<6>[   72.258997 / 05-21 22:27:31.935][2] Exception stack(0xd7f03fb0 to 0xd7f03ff8)
<6>[   72.259009 / 05-21 22:27:31.935][2] 3fa0:                                     71488688 00000000 71488688 131e3218
<6>[   72.259023 / 05-21 22:27:31.935][2] 3fc0: 00263c64 00000001 00000000 131e2bf0 00000000 92778200 71488688 131e3218
<6>[   72.259036 / 05-21 22:27:31.935][2] 3fe0: 00000000 885bc480 00000000 73a7c9c0 00070030 ffffffff 

(개인블로그)
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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.