最近 Linux kernel 2.4 的 Backtrace 不見了, 這樣實在非常不好 Debug,
查了一下才發現, 少加了一些 Flags.
原來會顯示(部份)
Process swapper (pid: 1, stack limit = 0xc030a368)
Stack: (0xc030bfc0 to 0xc030c000)
bfc0: c0042410 c00424a8 c030a000 c020f558 c0011118 c030a000 c020f558 c0200d10
bfe0: 000191cc c00430d8 c00430a4 c01fe000 c0237948 c0046974 c4a57686 1b469a8c
Backtrace: no frame pointer
Code: c0237ba0 e92d40f0 e3a04000 e1a05004 (e5854000)
Kernel panic: Attempted to kill init!
這時是沒有 frame pointer , 這時在 compile 時加上參數 -fomit-frame-pointer
就可以了. 以 Linux 2.4 ARM Platform 為例, 請在 arch/arm/Makefile 的 cflags 加上
這個參數
加了以後, 程式有問題就會顯示
Process swapper (pid: 1, stack limit = 0xc0efa368)
Stack: (0xc0efbf9c to 0xc0efc000)
bf80: c0042a70
bfa0: c0042b08 c0efa000 c0217558 c0efbfd8 c0efbfbc c00114cc c0011820 c0efa000
bfc0: c0217558 c0208d10 00019834 c0efbff4 c0efbfdc c00430e0 c00114c8 c00430a4
bfe0: c0206000 c023f948 00000000 c0efbff8 c0046a54 c00430b4 00000000 00000000
Backtrace:
Function entered at [] from [ ]
r7 = C0217558 r6 = C0EFA000 r5 = C0042B08 r4 = C0042A70
Function entered at [] from [ ]
Function entered at [] from [ ]
r6 = C023F948 r5 = C0206000 r4 = C00430A4
Code: e92dd8f0 e24cb004 e3a04000 e1a05004 (e5854000)
Kernel panic: Attempted to kill init!
但是這一堆 Code, 實在是看不懂, 那要怎麼辦呢? 還好 Linux kernel 2.4 有提供一個
Tool: ksymoops 可以用.
執行指令
ksymoops -m System.map
將 Backtrace 那一段貼上去
Backtrace:
Function entered at [] from [ ]
r7 = C0217558 r6 = C0EFA000 r5 = C0042B08 r4 = C0042A70
Function entered at [] from [ ]
Function entered at [] from [ ]
r6 = C023F948 r5 = C0206000 r4 = C00430A4
Code: e92dd8f0 e24cb004 e3a04000 e1a05004 (e5854000)
Kernel panic: Attempted to kill init!
Backtrace:
Function entered at [] from [ ]
r7 = C0217558 r6 = C0EFA000 r5 = C0042B08 r4 = C0042A70
Function entered at [] from [ ]
Function entered at [] from [ ]
r6 = C023F948 r5 = C0206000 r4 = C00430A4
Code: e92dd8f0 e24cb004 e3a04000 e1a05004 (e5854000)
就會得到結果
Trace; c0011810 <$a+0/0>
Trace; c00114cc>>r7; c0217558 <__machine_arch_type+0/4>
>>r5; c0042b08 <__initcall_end+0/4f8>
>>r4; c0042a70 <$d+0/0>Trace; c00114b8 <$a+0/0>
Trace; c00430e0
Trace; c00430a4
Trace; c0046a54>>r6; c023f948
>>r5; c0206000
>>r4; c00430a4Code; c0011814
00000000 <_EIP>:
Code; c0011814
0: f0 d8 2d e9 04 b0 4c lock fsubrs 0x4cb004e9
Code; c001181b
7: e2 00 loop 9 <_EIP+0x9>
Code; c001181d
9: 40 inc %eax
Code; c001181e
a: a0 e3 04 50 a0 mov 0xa05004e3,%al
Code; c0011823
f: e1 00 loope 11 <_EIP+0x11>
Code; c0011825
11: 40 inc %eax
Code; c0011826
12: 85 e5 test %esp,%ebpKernel panic: Attempted to kill init!
這樣就可以清楚的知道, 到底是那邊發生問題了.
Linux kernel 2.6 己經內建在 Option 內了, 在 Option “[ ] Configure standard kernel features (for small systems) “, Enable 後就看得到了.
雖然是小問題, 不過也是要找一下的.
ref.
Jserv GCC 函式追蹤功能
Linux Device Driver 3 Chapter 4. Debugging Techniques
[Tags] Linux kernel, Debug [/Tags]
maniac
我怎麼記得 gcc 的 help 裡有這麼一段:
-fomit-frame-pointer When possible do not generate stack frames
這樣子編出來的東西好像不會跑出 frame pointer 出來… ^^
(至少在 x86 上編東西是這樣…)
不過我在 debug 的時候, 都是開 -O0, 省得最佳化把我的一堆東西都最佳化掉了
richliu
Linux kernel 不能開 -O0, 會出問題的.
很多時候, 僅僅是 -O2 改 -O3 , 因為流程改變關係, Bug 就不會出現.
maniac
最近想要自己編個 mplayer.exe 出來(等別人的太慢), 所以就 svn co 一下, 然後備齊了一些有的沒有的函式庫, 然後開始編
編著編著, 出現了這個錯誤
cabac.h:513: error: can’t find a register in class `GENERAL_REGS’ while reloading `asm’
去看這一段, 也沒什麼啊, 就是用的 register 多了點… 7 個, 可是在預設的情況之下是只有 6 個 (eax, ebx, ecx, edx, esi, edi) 可用, 所以加了個 -fomit-frame-pointer 再下去 try 看看(理論上會多個 ebp 可用), 結果還是失敗
然後 try 了半天, 最後加上了該X的-O2… 過了…
gcc 我真搞不懂你啊~~~
灰熊
我也碰到了同样的问题,设成-O2就可以了。