version 1.16, 2016/11/19 13:15:10 |
version 1.17, 2017/02/06 17:24:32 |
|
|
<h3>How do I gather further information from a kernel crash?</h3><p> |
<h3>How do I gather further information from a kernel crash?</h3><p> |
|
|
A typical kernel crash on OpenBSD might look like this: |
A typical kernel crash on OpenBSD might look like this: |
(things to watch for are marked with bold font) |
|
|
|
<blockquote><pre> |
<blockquote><pre> |
kernel: page fault trap, code=0 |
kernel: page fault trap, code=0 |
|
|
ddb> |
ddb> |
</pre></blockquote> |
</pre></blockquote> |
|
|
The first command to run from the <tt>ddb></tt> prompt is <tt>trace</tt> |
This crash happened at offset <tt>0x263</tt> in the function <tt>_pf_route</tt>. |
(see <a href="http://man.openbsd.org/ddb">ddb(4)</a> for details): |
|
|
|
|
<p> |
|
The first command to run from the |
|
<a href="http://man.openbsd.org/ddb">ddb(4)</a> prompt is <tt>trace</tt>: |
|
|
<blockquote><pre> |
<blockquote><pre> |
ddb> <b>trace</b> |
ddb> <b>trace</b> |
<b>_pf_route</b>(e28cb7e4,e28bc978,2,1fad,d0b8b120) at <b>_pf_route+0x263</b> |
<b>_pf_route</b>(e28cb7e4,e28bc978,2,1fad,d0b8b120) at <b>_pf_route+0x263</b> |
|
|
do the following: |
do the following: |
|
|
<p> |
<p> |
Find the source file where the crashing function is defined in. |
Find the source file where the crashing function is defined. |
In this example, that would be <tt>pf_route()</tt> in <tt>sys/net/pf.c</tt>. |
In this example, that would be <tt>pf_route()</tt> in <tt>/sys/net/pf.c</tt>. |
Recompile that source file with debug information: |
Use <a href="http://man.openbsd.org/objdump">objdump(1)</a> to get the |
|
|
<blockquote><pre> |
|
# <b>cd /usr/src/sys/arch/$(uname -m)/compile/GENERIC</b> |
|
# <b>rm obj/pf.o</b> |
|
# <b>DEBUG=-g make pf.o</b> |
|
</pre></blockquote> |
|
|
|
Then use <a href="http://man.openbsd.org/objdump">objdump(1)</a> to get the |
|
disassembly: |
disassembly: |
|
|
<blockquote><pre> |
<blockquote><pre> |
# <b>objdump --line --disassemble --reloc obj/pf.o >pf.dis</b> |
$ <b>cd /sys/arch/$(uname -m)/compile/GENERIC</b> |
|
$ <b>objdump -dlr obj/pf.o >/tmp/pf.dis</b> |
</pre></blockquote> |
</pre></blockquote> |
|
|
In the output, grep for the function name: |
In the output, grep for the function name: |
|
|
<blockquote><pre> |
<blockquote><pre> |
# <b>grep "<_pf_route>:" pf.dis</b> |
$ <b>grep "<_pf_route>:" /tmp/pf.dis</b> |
0000<b>7d88</b> <_pf_route>: |
0000<b>7d88</b> <_pf_route>: |
</pre></blockquote> |
</pre></blockquote> |
|
|
Take this first hex number and add the offset from the <tt>Stopped at</tt> line: |
Take this first hex number <tt>7d88</tt> and add the offset <tt>0x263</tt> from |
<tt>0x7d88 + 0x263 == 0x7feb</tt>. |
the <tt>Stopped at</tt> line: |
|
|
<p> |
<blockquote><pre> |
|
$ <b>printf '%x\n' $((0x7d88 + 0x263))</b> |
|
7feb |
|
</pre></blockquote> |
|
|
Scroll down to that line (the assembler instruction should match the one |
Scroll down to that line (the assembler instruction should match the one |
quoted in the <tt>Stopped at</tt> line), then up to the nearest C line number: |
quoted in the <tt>Stopped at</tt> line), then up to the nearest C line number: |
|
|
<blockquote><pre> |
<blockquote><pre> |
# <b>more pf.dis</b> |
$ <b>more /tmp/pf.dis</b> |
/usr/src/sys/arch/i386/compile/GENERIC/../../../../net/pf.c:<b>3872</b> |
/sys/net/pf.c:<b>3872</b> |
7fe7: 0f b7 43 02 movzwl 0x2(%ebx),%eax |
7fe7: 0f b7 43 02 movzwl 0x2(%ebx),%eax |
<b>7feb</b>: 8b 57 40 mov 0x40(%edi),%edx |
<b>7feb</b>: 8b 57 40 mov 0x40(%edi),%edx |
7fee: 39 d0 cmp %edx,%eax |
7fee: 39 d0 cmp %edx,%eax |
|
|
So, it's precisely line <tt>3872</tt> of <tt>pf.c</tt> that crashes: |
So, it's precisely line <tt>3872</tt> of <tt>pf.c</tt> that crashes: |
|
|
<blockquote><pre> |
<blockquote><pre> |
# <b>cat -n pf.c | head -n 3872 | tail -n 1</b> |
$ <b>nl -ba /sys/net/pf.c | sed -n 3872p</b> |
3872 if ((u_int16_t)ip->ip_len <= ifp->if_mtu) { |
3872 if ((u_int16_t)ip->ip_len <= ifp->if_mtu) { |
</pre></blockquote> |
</pre></blockquote> |
|
|
Note that the kernel that produced the crash output and the object file |
The kernel that produced the crash output and the object file for objdump must |
for objdump must be compiled from the exact same source file, otherwise |
be compiled from the exact same source file, otherwise the offsets won't match. |
the offsets won't match. |
|
|
|
<p> |
<p> |
If you provide both the ddb trace output and the relevant objdump section, |
If you provide both the ddb trace output and the relevant objdump section, |