Cleanup
[ikiwiki.git] / docs / user / DebugKernelCrashDumps.mdwn
1 # Debug the DragonFly kernel 
2
3
4
5 This chapter should give you an introduction how to obtain a crash dump after a kernel panic and how to extract useful information for the developers out of the dump.
6
7
8
9 [[!toc levels=3 ]]
10 ***Contributed by Matthias Schmidt***
11
12
13
14 ## Configure your system 
15
16 Normally a crash dump is saved in your swap partition after a crash.  If you reboot your machine the next time the dump is extracted by [savecore(8)](http://leaf.dragonflybsd.org/cgi/web-man?command#savecore&section8) from the partition and stored into `/var/crash`.  Due to the fact that `/var` is a relatively small partition it could be possible that the dump isn't saved, because the dump size is larger than the remaining size.
17
18
19
20 To circumvent this problem you can change the default settings in `/etc/rc.conf`:
21
22
23
24 [[!table  data="""
25 | `dumpdev` | Indicates the device (usually a swap partition) to which a crash dump should be written in the event of a system crash. 
26  `dumpdir` | savecore(8) will save that crash dump and a copy of the kernel to the directory specified by the dumpdir variable.  The default value is /var/crash.  You can set this to another directory on another partition with more space available to safely obtain the dump. |
27
28 """]]
29
30 If you are unsure about your swap partition device, use [swapinfo(8)](http://leaf.dragonflybsd.org/cgi/web-man?command#swapinfo&section8) or look into `/etc/fstab` :
31
32     
33
34     # swapinfo 
35
36     Device          1K-blocks     Used    Avail Capacity  Type
37
38     /dev/ad0s1b       1048448        0  1048448     0%    Interleaved
39
40     
41
42     # cat /etc/fstab | grep swap
43
44     /dev/ad0s1b             none            swap    sw              0       0
45
46
47
48
49
50 ### Enable debugging options in your kernel config 
51
52
53
54 If you don't know how to configure a custom kernel, look into [Configuring the DragonFly Kernel](kernelconfig.html).  You have to add the following lines to compile your kernel with debugging symbols:
55
56     
57
58     makeoptions     DEBUG=-g                #Build kernel with gdb(1) debug symbols
59
60
61
62 If you want additional support for the interactive kernel debugger [ddb(4)](http://leaf.dragonflybsd.org/cgi/web-man?command#ddb&section4) and invariant debugging, also add these lines:
63
64     
65
66     # Debugging for Development
67
68     options         DDB
69
70     options         DDB_TRACE
71
72     options         INVARIANTS
73
74
75
76 ## How does a crash look like? 
77
78
79
80 Easy answer:  Your system stopped working.  Complicated one:  Your system occurred a [panic(9)](http://leaf.dragonflybsd.org/cgi/web-man?command#panic&section9) and drops into [ddb(4)](http://leaf.dragonflybsd.org/cgi/web-man?command=ddb&section=4), the interactive kernel debugger.
81
82 The output while seeing a crash might look this:
83
84     
85
86     Fatal trap 12: page fault while in kernel mode
87
88     fault virtual address   = 0xd0686f55
89
90     fault code              = supervisor read, page not present
91
92     instruction pointer     = 0x8:0xc02ddb9a
93
94     stack pointer           = 0x10:0xcec0fb18
95
96     frame pointer           = 0x10:0xcec0fb18
97
98     code segment            = base 0x0, limit 0xfffff, type 0x1b
99
100                             = DPL 0, pres 1, def32 1, gran 1
101
102     processor eflags        # interrupt enabled, resume, IOPL  0
103
104     current process         = 50725 (sysctl)
105
106     current thread          = pri 6
107
108                                                                                                           
109
110     panic: from debugger
111
112
113
114 Before your machine reboots a crash dump is saved into your swap partition (if you have one and don't disabled crash dumps).  Writing the dump to disk takes some time depending on your machine and the amount of RAM installed.  This might look like this:
115
116     
117
118     dumping to dev #ad/0x20001, blockno 1049088
119
120     dump 511 510 509 508 507 506 505 
121
122     [...]
123
124     26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 succeeded
125
126
127
128 Now your machine reboots, checks its file system and finally extracts the crash dump from the swap partition to your `dumpdir` (see `rc.conf` setting above).  If your `/var` partition is to small, you'll see an error similar to the following:
129
130     
131
132     savecore: reboot after panic: from debugger
133
134     savecore: no dump, not enough free space on device (231420 available, need 541840)
135
136
137
138 If this happens, you have to extract the crash dump yourselves.  See next Section how to do this.
139
140 ### Extract a crash dump manually 
141
142 You can use [savecore(8)](http://leaf.dragonflybsd.org/cgi/web-man?command#savecore&section8) to copy your currently running kernel and the associated crash dump to a particular directory you have to specify (we use `/usr/crash` here in the example):
143
144     
145
146     # mkdir -p /usr/crash
147
148     # chmod 700 /usr/crash
149
150     # savecore /usr/crash/
151
152     [...]
153
154
155
156 This will take some time dependent on the speed of your machine.  See the man page of savecore(8) for more available options.
157
158 ### Upload the crash dump 
159
160 If you don't have the ability or skills to debug are crash yourselves, please upload the complete content of your crash directory to a public available location (HTTP, FTP web space or your leaf account) and send a detailed bug report to the bugs@dragonflybsd.org list.  If its possible please tar and compress (gzip, bzip2) the directory to save disk space and bandwith.
161
162
163
164 ## Debug the crash dump with kgdb 
165
166 The [kgdb(1)](http://leaf.dragonflybsd.org/cgi/web-man?command#kgdb&section1) utility is a debugger based on gdb(1) that allows debugging of kernel core files.
167
168 ### kgdb extesions 
169
170 To get some handy helper command execute the following command before starting kgdb:
171
172     
173
174     source /usr/src/test/debug/gdb.kernel
175
176
177
178 This gives you several new commands like kldstat (displays all loaded modules) or psx (displays all running processes).
179
180 Start kgdb as follows:
181
182     
183
184     # cd /usr/crash
185
186     # ls -l
187
188     -rw-r--r--  1 root  wheel     2B Jan  7 17:07 bounds
189
190     -rw-r--r--  1 root  wheel    17M Jan  7 17:08 kernel.0
191
192     -rw-------  1 root  wheel   512M Jan  7 17:08 vmcore.0
193
194     # kgdb kernel.0 vmcore.0
195
196
197
198 kgdb(1) will show you the panic message after start.  The first thing to do is to obtain a ***backtrace*** with the ***bt*** command:
199
200     
201
202     Unread portion of the kernel message buffer:
203
204     
205
206     
207
208     Fatal trap 12: page fault while in kernel mode
209
210     fault virtual address   = 0xd0686f55
211
212     fault code              = supervisor read, page not present
213
214     instruction pointer     = 0x8:0xc02ddb9a
215
216     stack pointer           = 0x10:0xcec0fb18
217
218     frame pointer           = 0x10:0xcec0fb18
219
220     code segment            = base 0x0, limit 0xfffff, type 0x1b
221
222     current process         = 50725 (sysctl)
223
224     current thread          = pri 6 
225
226     
227
228     panic: from debugger
229
230     
231
232     
233
234     Fatal trap 3: breakpoint instruction fault while in kernel mode
235
236     instruction pointer     = 0x8:0xc03136a4
237
238     stack pointer           = 0x10:0xcec0f92c
239
240     frame pointer           = 0x10:0xcec0f934
241
242     code segment            = base 0x0, limit 0xfffff, type 0x1b
243
244                             = DPL 0, pres 1, def32 1, gran 1
245
246     processor eflags        # interrupt enabled, IOPL  0
247
248     current process         = 50725 (sysctl)
249
250     current thread          = pri 6 
251
252     
253
254     panic: from debugger
255
256     Uptime: 3h57m22s
257
258     
259
260     dumping to dev #ad/0x20001, blockno 1049088
261
262     dump 511 510 509 508 507 506 505 504 503 502 501 500 499 498 
263
264     [...]
265
266     40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 
267
268     
269
270     GNU gdb 6.2.1
271
272     Copyright 2004 Free Software Foundation, Inc.
273
274     GDB is free software, covered by the GNU General Public License, and you are
275
276     welcome to change it and/or distribute copies of it under certain conditions.
277
278     Type "show copying" to see the conditions.
279
280     There is absolutely no warranty for GDB.  Type "show warranty" for details.
281
282     This GDB was configured as "i386-dragonfly".
283
284     (kgdb) bt
285
286     #0  dumpsys () at thread.h:83
287
288     #1  0xc01c4e1b in boot (howto=260) at /usr/src/sys/kern/kern_shutdown.c:375
289
290     #2  0xc01c4f3c in panic (fmt=Variable "fmt" is not available.
291
292     ) at /usr/src/sys/kern/kern_shutdown.c:800
293
294     #3  0xc0149be5 in db_panic (addr=Could not find the frame base for "db_panic".
295
296     ) at /usr/src/sys/ddb/db_command.c:447
297
298     #4  0xc014a250 in db_command_loop () at /usr/src/sys/ddb/db_command.c:343
299
300     #5  0xc014c7bc in db_trap (type#12, code0) at /usr/src/sys/ddb/db_trap.c:71
301
302     #6  0xc03137f7 in kdb_trap (type#12, code0, regs=0xcec0fad0) at /usr/src/sys/platform/pc32/i386/db_interface.c:148
303
304     #7  0xc032384b in trap_fatal (frame#0xcec0fad0, evaVariable "eva" is not available.
305
306     ) at /usr/src/sys/platform/pc32/i386/trap.c:1091
307
308     #8  0xc03239b0 in trap_pfault (frame#0xcec0fad0, usermode0, eva=3496505173)
309
310         at /usr/src/sys/platform/pc32/i386/trap.c:997
311
312     #9  0xc03241a0 in trap (frame=0xcec0fad0) at /usr/src/sys/platform/pc32/i386/trap.c:680
313
314     #10 0xc0314506 in calltrap () at /usr/src/sys/platform/pc32/i386/exception.s:783
315
316     #11 0xc02ddb9a in strlen (str=0xd0686f55 <Address 0xd0686f55 out of bounds>) at /usr/src/sys/libkern/strlen.c:41
317
318     #12 0xc02c2153 in sysctl_vm_zone (oidp#0xc03b42a0, arg10x0, arg2=0, req=0xcec0fc08) at /usr/src/sys/vm/vm_zone.c:447
319
320     #13 0xc01cf935 in sysctl_root (oidp=Variable "oidp" is not available.
321
322     ) at /usr/src/sys/kern/kern_sysctl.c:1193
323
324     #14 0xc01cfa27 in userland_sysctl (name#0xcec0fc90, namelen2, old=0x0, oldlenp=0xbfbfe8f0, inkernel=0, new=0x0, 
325
326         newlen#0, retval0xcec0fc8c) at /usr/src/sys/kern/kern_sysctl.c:1268
327
328     #15 0xc01cfc28 in sys___sysctl (uap=0xcec0fcf0) at /usr/src/sys/kern/kern_sysctl.c:1211
329
330     #16 0xc0323ccb in syscall2 (frame=0xcec0fd40) at /usr/src/sys/platform/pc32/i386/trap.c:1339
331
332     #17 0xc03145a5 in Xint0x80_syscall () at /usr/src/sys/platform/pc32/i386/exception.s:872
333
334     #18 0x08055d38 in ?? ()
335
336     #19 0xbfbfe86c in ?? ()
337
338     #20 0x0000002f in ?? ()
339
340     #21 0x00000000 in ?? ()
341
342     #22 0x00000000 in ?? ()
343
344     #23 0x00000000 in ?? ()
345
346     #24 0x00000000 in ?? ()
347
348     #25 0x13c4b000 in ?? ()
349
350     #26 0x00000001 in ?? ()
351
352     #27 0xc03c2bf8 in intr_info_ary ()
353
354     #28 0xcec0f8d4 in ?? ()
355
356     #29 0xcec0f8c4 in ?? ()
357
358     #30 0xc8076300 in ?? ()
359
360     #31 0xc01cac5a in lwkt_preempt (ntd#0x2, critpriCannot access memory at address 0xbfbfe8a4
361
362     ) at /usr/src/sys/kern/lwkt_thread.c:893
363
364     Previous frame inner to this frame (corrupt stack?)
365
366
367
368 kgdb(1) gives you the ability to look into specific frames, display variable content and obtain the source code (if your kernel was compiled with -g):
369
370     
371
372     (kgdb) f 13
373
374     #13 0xc01cf935 in sysctl_root (oidp=Variable "oidp" is not available.
375
376     ) at /usr/src/sys/kern/kern_sysctl.c:1193
377
378     1193                    error = oid->oid_handler(oid, oid->oid_arg1, oid->oid_arg2,
379
380     (kgdb) l
381
382     1188
383
384     1189            if ((oid->oid_kind & CTLTYPE) # CTLTYPE_NODE)
385
386     1190                    error = oid->oid_handler(oid, (int *)arg1 + indx, arg2 - indx,
387
388     1191                        req);
389
390     1192            else
391
392     1193                    error = oid->oid_handler(oid, oid->oid_arg1, oid->oid_arg2,
393
394     1194                        req);
395
396     1195            return (error);
397
398     1196    }
399
400     1197
401
402     (kgdb) p *oid
403
404     $1 # {oid_parent  0xc03cbda8, oid_link = {sle_next = 0x0}, oid_number = 283, oid_kind = -2147483645, oid_arg1 = 0x0, 
405
406       oid_arg2 # 0, oid_name  0xc03616ad "zone", oid_handler = 0xc02c20fa <sysctl_vm_zone>, oid_fmt = 0xc036a56f "A", 
407
408       oid_refcnt # 0, oid_descr  0xc036906a "Zone Info"}
409
410
411
412 ## Further Information 
413
414 To get more information about how to use a debugger, look here:
415
416
417 * [Man page of kgdb(1)](http://leaf.dragonflybsd.org/cgi/web-man?command#kgdb&section1)
418
419
420 * [Man page of gdb(1)](http://leaf.dragonflybsd.org/cgi/web-man?command#gdb&section1)
421
422
423 * [How to retrieve symbols from kernel modules](http://leaf.dragonflybsd.org/mailarchive/kernel/2005-11/msg00065.html)
424
425
426 * [FreeBSD Developers Handbook](http://www.freebsd.org/doc/en_US.ISO8859-1/books/developers-handbook/book.html#KERNELDEBUG)
427
428
429 * [GDB Manual](http://sourceware.org/gdb/documentation/)
430
431
432 * [Debug tutorial from Greg Lehey](http://www.lemis.com/grog/Papers/Debug-tutorial/tutorial.pdf)
433