Annotation of prex-old/doc/html/doc/debug.html, Revision 1.1.1.1
1.1 nbrk 1: <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
2: <html>
3: <head>
4: <title>Prex Kernel Debugging Tips and Tricks</title>
5: <meta content="text/html; charset=ISO-8859-1" http-equiv="content-type">
6: <meta name="keywords" content="Prex, embedded, real-time, operating system, RTOS, open source, free">
7: <meta name="author" content="Kohsuke Ohtani">
8: <link rel="stylesheet" type="text/css" href="../default.css" media="screen">
9: <link rel="stylesheet" type="text/css" href="../print.css" media="print">
10: </head>
11: <body>
12: <div id="top">
13: </div>
14: <div id="middle">
15:
16: <table id="content" cellpadding="0" cellspacing="0">
17: <tbody>
18:
19: <tr>
20: <td id="header" colspan="2" valign="top">
21: <table width="100%" border="0" cellspacing="0" cellpadding="0">
22: <tr>
23: <td id="logo">
24: <a href="http://prex.sourceforge.net/">
25: <img alt="Prex logo" src="../img/logo.gif" border="0"
26: style="width: 281px; height: 56px;"></a>
27: </td>
28: <td id="brief" align="right" valign="bottom">
29: An Open Source, Royalty-free,<br>
30: Real-time Operating System
31: </td>
32: </tr>
33: </table>
34: </td>
35: </tr>
36:
37: <tr>
38: <td id="directory" style="vertical-align: top;">
39: <a href="http://prex.sourceforge.net/">Prex Home</a> >
40: <a href="index.html">Document Index</a> >
41: Kernel Debugging Tips and Tricks
42: </tr>
43: <tr><td class="pad" colspan="2" style="vertical-align: top;"></td></tr>
44:
45: <tr>
46: <td id="main" style="vertical-align: top;">
47: <h1>Prex Kernel Debugging Tips and Tricks</h1>
48:
49: <i>Version 1.0, 2005/09/05</i><br>
50:
51: <h3>Table of Contents</h3>
52:
53: <ul>
54: <li><a href="#dbg">Building a Debugging Kernel</a></li>
55: <li><a href="#print">Kernel Print</a></li>
56: <li><a href="#panic">Kernel Panic</a></li>
57: <li><a href="#assert">Assertion Check</a></li>
58: <li><a href="#trace">Function Trace</a></li>
59: <li><a href="#dump">Kernel Dump</a></li>
60: <li><a href="#gdb">Remote debugging with GDB</a></li>
61: </ul>
62: <br>
63: <br>
64:
65: <h2 id="dbg">Building a Debugging Kernel</h2>
66: <p>
67: The Prex kernel is compiled with debugging version by default.
68: The debugging version will have the following extra functions
69: compared with the release version.
70: <ul>
71: <li>printk() to output the debug message.</li>
72: <li>panic() log for the fatal error.</li>
73: <li>ASSERT() for the assertion check.</li>
74: <li>Kernel function trace.</li>
75: <li>Dump of the kernel objects.</li>
76: </ul>
77: <p>
78: However, you should care about the following two points.
79: </p>
80: <ul>
81: <li>The size of executable image will become larger than
82: the release version.</li>
83: <li>The execution speed becomes slower than the release version.
84: </ul>
85: <p>
86: In order to build a release version, you must set the shell variable
87: named NDEBUG to 1 before compiling the kernel.
88: </p>
89: <pre class="terminal">
90: $ export NDEBUG=1
91: </pre>
92:
93:
94: <h2 id="print">Kernel Print</h2>
95: <p>
96: The most powerful tool for kernel debugging is printk(). You can check the
97: code path, or get the data value by putting the printk() anywhere in
98: the kernel code.
99: </p>
100: <p>
101: printk() is the subset of printf() in standard C library. You can use
102: only following identifiers for the output string.
103: </p>
104: <ul>
105: <li>%d - Decimal signed integer</li>
106: <li>%x - Hex integer</li>
107: <li>%u - Unsigned integer</li>
108: <li>%c - Character</li>
109: <li>%s - String</li>
110: </ul>
111:
112: <h2 id="panic">Kernel Panic</h2>
113: <h3>What is Kernel Panic?</h3>
114: <p>
115: Panic is used to detect unrecoverable error in the kernel.
116: The kernel code can call panic() routine anytime if it
117: encounters a fatal error. panic() function will stop the system and
118: display the message if output device is available. If the kernel is not
119: compiled with debug mode, panic() will just reset the system without
120: any message. When GDB is connect to the kernel, the control will be
121: dropped to the debugger in panic().
122: </p>
123:
124: <h3>Panic Screen</h3>
125: The following is a sample screen of panic() on i386.
126: <pre class="terminal">
127: =====================================================
128: Kernel panic!
129: Failed to create interrupt thread
130: =====================================================
131: ============================
132: Trap 3: Breakpoint
133: ============================
134: Trap frame 80002f28 error 0
135: eax 00000001 ebx 800110ac ecx ffffffff edx 800192b6 esi 00000000 edi 00000000
136: eip 80014289 esp 80002f28 ebp 80002f78 eflags 00000002
137: cs 00000010 ss 00000018 ds 00000018 es 00000018 esp0 00002fff
138: >> interrupt is disabled
139: Stack trace:
140: 80011103
141: 8001130c
142: 80010115
143: </pre>
144:
145: <h2 id="assert">Assertion Check</h2>
146:
147: <h3>What is Assertion Check?</h3>
148: <p>
149: The assert macro puts error messages into the kernel.
150: If the specified expression in ASSERT() is false, it displays
151: the message to the output device and stops the system.
152: </p>
153: <p>
154: For example, the following ASSERT() macro is put to the entry of the
155: irq_attach() routine.
156: This means the caller of irq_attach() must provide a valid
157: function pointer for ISR (interrupt service routine).
158: </p>
159: <pre>
160: int irq_attach(int vector, int prio, int shared, int (*isr)(int), void (*ist)(int))
161: {
162: ASSERT(isr != NULL);
163: ...
164: </pre>
165: If the kernel detect the invalid argument for isr, it will cause
166: a panic() with the following message.
167: <pre class="terminal">
168: Assertion failed: irq.c line:120 in irq_attach() 'isr != NULL'
169: </pre>
170: <p>
171: The important point is ASSERT() macro is only enabled with the kernel
172: debug version. If the assertion is caused by an application bug
173: or h/w bug, it should not be covered by ASSERT(). Such fault should be handled
174: as an "error" properly.
175: </p>
176:
177: <h3>IRQ Assertion</h3>
178: <p>
179: There are some kernel routines that can not be called during
180: an interrupt context. For example, the following functions can not
181: be called by ISR.
182: </p>
183: <ul>
184: <li>IRQ control code. (irq_attach() or irq_detach).</li>
185: <li>The system call code that requires an user mode context.</li>
186: <li>The kernel code that assumes it can synchronize by scheduling lock.
187: (kmem).</li>
188: </ul>
189: <p>
190: In order to detect the invalid call of these functions, the kernel defines
191: a ASSERT_IRQ() macro. The kernel developer can put this macro in the
192: head of the kernel routine which can not be called by ISR.
193: When ISR call such routine, the kernel will report the problem with panic()
194: message.
195: </p>
196:
197: <h2 id="trace">Function Trace</h2>
198: The kernel trace is used to log the entry/exit of all functions at
199: runtime.
200: It is useful to debug the timing critical issue related to
201: an interrupt handler.
202:
203: <h3>Installing the kernel trace</h3>
204: <p>
205: You must set the shell variable named KTRACE to 1 before compiling the kernel.
206: </p>
207: <pre class="terminal">
208: $ export KTRACE=1
209: </pre>
210: <p>
211: The kernel function trace is disabled by default. If you get the error
212: from gcc, you should check the function with "extern inline" in the header
213: file. Such function must be replaced as "static inline" routine to
214: enable the function trace.
215: </p>
216:
217: <h3>Using the kernel trace</h3>
218: <p>
219: The following functions are available for the kernel trace.
220: </p>
221: <ul>
222: <li>trace_on: Enable a function trace.</li>
223: <li>trace_off: Disable a function trace.</li>
224: <li>trace_dump: Dump the latest function log.</li>
225: </ul>
226: <p>
227: The trace code is using a ring buffer to store the log data.
228: So, older information will be disposed when newer log is filled in the buffer.
229: </p>
230:
231: <h2 id="dump">Kernel Dump</h2>
232:
233: <h3>Installing Kernel Dump</h3>
234: <p>
235: The kernel dump is used to dump the current status of each kernel
236: objects.
237: To install the kernel dump function, you must uncomment the following line
238: in config.h.
239: </p>
240: <pre>#define CONFIG_KDUMP 1</pre>
241: <p>
242: If you assign magic keys for the kernel dump, you can get the
243: kernel dump as far as the keyboard IRQ is enabled.
244: The key assignment of the kernel dump depends on each platform.
245: </p>
246:
247: <h3>Dump Sample</h3>
248: <p>
249: The following dump screen was got with Prex-i386pc.
250: </p>
251: <pre class="terminal">
252: Kernel dump usage:
253: F1=help F2=thread F3=task F4=object F5=timer F6=irq F7=dev F8=mem
254:
255: thread_dump:
256: mod thread task stat pol prio base lock qntm total susp sleep event
257: --- -------- -------- ---- ---- ---- ---- ---- ---- -------- ---- ------------
258: Knl 8002a014 800191a0 SLP FIFO 022 022 1 50 1 0 interrupt
259: Knl 80029a54 800191a0 SLP FIFO 020 020 1 50 0 0 interrupt
260: Knl 80029464 800191a0 SLP RR 015 015 1 50 0 0 timer
261: Knl 800190c0 800191a0 RUN* FIFO 255 255 1 0 44719 0 -
262: Usr 8002a6e4 8002a574 SLP RR 200 200 1 50 3 0 kbd
263:
264: task_dump:
265: mod task nr_obj nr_thr map susp exc hdlr name
266: --- --------- ------ ------ -------- ---- -------- ------------
267: Knl 800191a0* 1 4 8001ac20 0 00000000 kernel
268: Usr 8002a574 1 1 8002a5e4 0 00000000 kmon
269:
270: IRQ dump:
271: vector isr ist ist-thr ist-prio count
272: ------ -------- -------- -------- -------- --------
273: 00 800110c8 00000000 00000000 0 54124
274: 01 80020784 800209f8 80029a54 20 66
275: 06 800212d0 80021360 8002a014 22 1
276: 12 80021aec 00000000 00000000 0 0
277:
278: device_dump:
279: device open close read write ioctl event name
280: -------- -------- -------- -------- -------- -------- -------- ------------
281: 8002a544 00000000 00000000 00000000 80020ecc 00000000 00000000 console
282: 80029fb4 80021b80 80021bb0 80021be0 00000000 00000000 00000000 mouse
283: 80029f44 8002161c 8002163c 80021714 80021800 800218dc 00000000 fd0
284: 800299e4 80020a30 80020a50 80020a70 00000000 00000000 00000000 kbd
285: 800299b4 00000000 00000000 80020584 00000000 00000000 00000000 rtc
286: 80029984 80022808 80022828 00000000 00000000 80022848 00000000 pm
287: 80029954 00000000 00000000 00000000 00000000 8002212c 00000000 cpu
288:
289: page_dump:
290: free pages:
291: start end size
292: -------- -------- --------
293: 00025000 - 00027000 2000
294: 00034000 - 0009f000 6b000
295: 00100000 - 040ff000 3fff000
296: used=200K free=65971K total=66171K
297:
298: kmem_dump: page=2 (8Kbyte) alloc=7056byte unused=1136byte
299: Allocated block:
300: Size 48 bytes => 11
301: Size 64 bytes => 5
302: Size 112 bytes => 1
303: Size 224 bytes => 4
304: Size 1040 bytes => 5
305: Free block:
306: Size 32 bytes => 1
307: Size 1072 bytes => 1
308:
309: vm_dump:
310: task=8002a574 map=8002a5e4 name=kmon
311: region virtual physical size flags
312: -------- -------- -------- -------- -----
313: 8002a624 08048000 0002c000 1000 R----
314: 8002a654 08049000 0002e000 1000 RW---
315: 8002a6b4 7ffff000 0002f000 1000 RW---
316: *total=12K bytes
317: </pre>
318:
319: <h2 id="gdb">Remote Debugging with GDB</h2>
320:
321: <h3>Installing the GDB remote stub</h3>
322: <p>
323: To install GDB stub into the Prex kernel, you must uncomment the following line
324: in config.h.
325: </p>
326: <pre>#define CONFIG_GDB 1</pre>
327: <p>
328: The GDB support is disabled by default.
329: </p>
330:
331: <h3>Connecting to the remote machine</h3>
332: You should specify the path to the symbol file.
333:
334: <pre class="terminal">(gdb) symbol-file /usr/src/prex/sys/prex.sym
335: (gdb) set remotebaud 115200
336: (gdb) target remote /dev/ttyS0</pre>
337:
338: <h3>Debugging Sample</h3>
339: <pre class="terminal">$ i386-elf-gdb
340: GNU gdb 6.3
341: Copyright 2004 Free Software Foundation, Inc.
342: GDB is free software, covered by the GNU General Public License, and you are
343: welcome to change it and/or distribute copies of it under certain conditions.
344: Type "show copying" to see the conditions.
345: There is absolutely no warranty for GDB. Type "show warranty" for details.
346: This GDB was configured as "--host=i686-pc-cygwin --target=i386-elf".
347: (gdb) symbol-file /usr/src/prex-0.1.2/sys/prex.sym
348: Reading symbols from /usr/src/prex-0.1.2/sys/prex.sym...done.
349: (gdb) set remotebaud 115200
350: (gdb) target remote /dev/ttyS0
351: Remote debugging using /dev/ttyS0
352: gdb_init () at gdb_glue.c:98
353: 98 }
354: (gdb) b context_init
355: Breakpoint 1 at 0x80010d27: file context.c, line 72.
356: (gdb) info break
357: Num Type Disp Enb Address What
358: 1 breakpoint keep y 0x80010d27 in context_init at context.c:72
359: (gdb) c
360: Continuing.
361:
362: Breakpoint 1, context_init (ctx=0x8001a16c, kstack=0x8002c414) at context.c:72
363: 72 {
364: (gdb) bt 3
365: #0 context_init (ctx=0x8001a16c, kstack=0x8002c414) at context.c:72
366: #1 0x800137fe in thread_init () at thread.c:469
367: #2 0x800125e0 in kernel_main () at main.c:76
368: (More stack frames follow...)
369: (gdb) list context_init
370: 67 *
371: 68 * @ctx: context id (pointer)
372: 69 * @kstack: kernel stack for the context
373: 70 */
374: 71 void context_init(context_t ctx, void *kstack)
375: 72 {
376: 73 struct kern_regs *k;
377: 74 struct cpu_regs *u;
378: 75
379: 76 ctx->uregs = (struct cpu_regs *)(kstack - sizeof(struct cpu_regs
380: ));
381: (gdb) up
382: #1 0x800137fe in thread_init () at thread.c:469
383: 469 context_init(&idle_thread.context, stk + KSTACK_SIZE);
384: (gdb) list
385: 464 panic("Failed to allocate idle stack");
386: 465 memset(stk, 0, KSTACK_SIZE);
387: 466 idle_thread.kstack = stk;
388: 467 printk("kernel stack size=%d\n", KSTACK_SIZE);
389: 468
390: 469 context_init(&idle_thread.context, stk + KSTACK_SIZE);
391: 470 list_insert(&kern_task.threads, &idle_thread.task_link);
392: 471 }
393: (gdb) b 465
394: Breakpoint 2 at 0x800137c6: file thread.c, line 465.
395: (gdb) c
396: Continuing.
397: </pre>
398:
399:
400:
401: </td>
402: </tr>
403: <tr>
404: <td id="footer" colspan="2" style="vertical-align: top;">
405: <a href="http://sourceforge.net">
406: <img src="http://sourceforge.net/sflogo.php?group_id=132028&type=1"
407: alt="SourceForge.net Logo" border="0" height="31" width="88"></a><br>
408: Copyright© 2005-2007 Kohsuke Ohtani
409: </td>
410: </tr>
411:
412: </tbody>
413: </table>
414:
415: </div>
416: <div id="bottom"></div>
417:
418: </body>
419: </html>
CVSweb