Kernel Debugging Techniques
Often the pivotal factor in achieving development timetables comes down to one's efficiency in finding and fixing bugs. Debugging inside the Linux kernel can be quite challenging. No matter how you approach it, kernel debugging will always be complex. This chapter examines some of the complexities and presents ideas and methods to improve your debugging skills inside the kernel and device drivers.
<several sections omitted>
At the start of this chapter, we said that one of the challenges identified in debugging kernel code results from compiler optimization. We noted that the Linux kernel is compiled by default with optimization level -O2. In the examples up to this point, we used -O1 optimization to simplify the debugging task. Here we illustrate one of the many ways optimization can complicate debugging.
The related Internet mail lists are strewn with questions related to what appear to be broken tools. Sometimes the poster reports that his debugger is singlestepping backward or that his line numbers do not line up with his source code. Here we present an example to illustrate the complexities that optimizing compilers bring to source-level debugging. In this example, the line numbers that gdb reports when a breakpoint is hit do not match up with the line numbers in our source file due to function inlining.
For this demonstration, we use the same debug code snippet as shown in Listing 14-4. (Parts of this is reproduced in Listing 14-9, below.) However, for this example, we have compiled the kernel with the compiler optimization flag -O2. This is the default for the Linux kernel. Listing 14-7 shows the results of this debugging session.
Listing 14-7
Optimized Architecture-Setup Code
$ ppc_44x-gdb --silent vmlinux
(gdb) target remote /dev/ttyS0
Remote debugging using /dev/ttyS0
breakinst () at arch/ppc/kernel/ppc-stub.c:825
825 }
(gdb) b panic
Breakpoint 1 at 0xc0016b18: file kernel/panic.c, line 74.
(gdb) b sys_sync
Breakpoint 2 at 0xc005a8c8: file fs/buffer.c, line 296.
(gdb) b yosemite_setup_arch
Breakpoint 3 at 0xc020f438: file arch/ppc/platforms/4xx/yosemite.c, line 116.
(gdb) c
Continuing.
Breakpoint 3, yosemite_setup_arch ()
at arch/ppc/platforms/4xx/yosemite.c:116
116 def = ocp_get_one_device(OCP_VENDOR_IBM, OCP_FUNC_EMAC, 0);
(gdb) l
111 struct ocp_def *def;
112 struct ocp_func_emac_data *emacdata;
113
114 /* Set mac_addr and phy mode for each EMAC */
115
116 def = ocp_get_one_device(OCP_VENDOR_IBM, OCP_FUNC_EMAC, 0);
117 emacdata = def->additions;
118 memcpy(emacdata->mac_addr, __res.bi_enetaddr, 6);
119 emacdata->phy_mode = PHY_MODE_RMII;
120
(gdb) p yosemite_setup_arch
$1 = {void (void)} 0xc020f41c <yosemite_setup_arch>
Referring back to Listing 14-4, (this can also be seen in Listing 14-9 below) notice that the function yosemite_setup_arch() actually falls on line 306 of the file yosemite.c. Compare that with Listing 14-7. We hit the breakpoint, but gdb reports the breakpoint at file yosemite.c line 116. It appears at first glance to be a mismatch of line numbers between the debugger and the corresponding source code. Is this a bug? First let's confirm what the compiler produced for debug information. Using the readelf5 tool described in Chapter 13, "Development Tools", we can examine the debug information for this function produced by the compiler.
$ ppc_44x-readelf --debug-dump=info vmlinux | grep -u6 \ yosemite_setup_arch | tail -n 7 DW_AT_name : (indirect string, offset: 0x9c04): yosemite_setup_arch DW_AT_decl_file : 1 DW_AT_decl_line : 307 DW_AT_prototyped : 1 DW_AT_low_pc : 0xc020f41c DW_AT_high_pc : 0xc020f794 DW_AT_frame_base : 1 byte block: 51 (DW_OP_reg1)
We don't have to be experts at reading DWARF2 debug records6 to recognize that the function in question is reported at line 307 in our source file. We can confirm this using the addr2line utility, also introduced in Chapter 13. Using the address derived from gdb in Listing 14-7:
$ ppc_44x-addr2line -e vmlinux 0xc020f41c arch/ppc/platforms/4xx/yosemite.c:307
At this point, gdb is reporting our breakpoint at line 116 of the yosemite.c file. To understand what is happening, we need to look at the assembler output of the function as reported by gdb. Listing 14-8 is the output from gdb after issuing the disassemble command on the yosemite_setup_arch() function.
Listing 14-8
Disassemble Function yosemite_setup_arch
(gdb) disassemble yosemite_setup_arch 0xc020f41c <yosemite_setup_arch+0>: mflr r0 0xc020f420 <yosemite_setup_arch+4>: stwu r1,-48(r1) 0xc020f424 <yosemite_setup_arch+8>: li r4,512 0xc020f428 <yosemite_setup_arch+12>: li r5,0 0xc020f42c <yosemite_setup_arch+16>: li r3,4116 0xc020f430 <yosemite_setup_arch+20>: stmw r25,20(r1) 0xc020f434 <yosemite_setup_arch+24>: stw r0,52(r1) 0xc020f438 <yosemite_setup_arch+28>: bl 0xc000d344 <ocp_get_one_device> 0xc020f43c <yosemite_setup_arch+32>: lwz r31,32(r3) 0xc020f440 <yosemite_setup_arch+36>: lis r4,-16350 0xc020f444 <yosemite_setup_arch+40>: li r28,2 0xc020f448 <yosemite_setup_arch+44>: addi r4,r4,21460 0xc020f44c <yosemite_setup_arch+48>: li r5,6 0xc020f450 <yosemite_setup_arch+52>: lis r29,-16350 0xc020f454 <yosemite_setup_arch+56>: addi r3,r31,48 0xc020f458 <yosemite_setup_arch+60>: lis r25,-16350 0xc020f45c <yosemite_setup_arch+64>: bl 0xc000c708 <memcpy> 0xc020f460 <yosemite_setup_arch+68>: stw r28,44(r31) 0xc020f464 <yosemite_setup_arch+72>: li r4,512 0xc020f468 <yosemite_setup_arch+76>: li r5,1 0xc020f46c <yosemite_setup_arch+80>: li r3,4116 0xc020f470 <yosemite_setup_arch+84>: addi r26,r25,15104 0xc020f474 <yosemite_setup_arch+88>: bl 0xc000d344 <ocp_get_one_device> 0xc020f478 <yosemite_setup_arch+92>: lis r4,-16350 0xc020f47c <yosemite_setup_arch+96>: lwz r31,32(r3) 0xc020f480 <yosemite_setup_arch+100>: addi r4,r4,21534 0xc020f484 <yosemite_setup_arch+104>: li r5,6 0xc020f488 <yosemite_setup_arch+108>: addi r3,r31,48 0xc020f48c <yosemite_setup_arch+112>: bl 0xc000c708 <memcpy> 0xc020f490 <yosemite_setup_arch+116>: lis r4,1017 0xc020f494 <yosemite_setup_arch+120>: lis r5,168 0xc020f498 <yosemite_setup_arch+124>: stw r28,44(r31) 0xc020f49c <yosemite_setup_arch+128>: ori r4,r4,16554 0xc020f4a0 <yosemite_setup_arch+132>: ori r5,r5,49152 0xc020f4a4 <yosemite_setup_arch+136>: addi r3,r29,-15380 0xc020f4a8 <yosemite_setup_arch+140>: addi r29,r29,-15380 0xc020f4ac <yosemite_setup_arch+144>: bl 0xc020e338 <ibm440gx_get_clocks> 0xc020f4b0 <yosemite_setup_arch+148>: li r0,0 0xc020f4b4 <yosemite_setup_arch+152>: lis r11,-16352 0xc020f4b8 <yosemite_setup_arch+156>: ori r0,r0,50000 0xc020f4bc <yosemite_setup_arch+160>: lwz r10,12(r29) 0xc020f4c0 <yosemite_setup_arch+164>: lis r9,-16352 0xc020f4c4 <yosemite_setup_arch+168>: stw r0,8068(r11) 0xc020f4c8 <yosemite_setup_arch+172>: lwz r0,84(r26) 0xc020f4cc <yosemite_setup_arch+176>: stw r10,8136(r9) 0xc020f4d0 <yosemite_setup_arch+180>: mtctr r0 0xc020f4d4 <yosemite_setup_arch+184>: bctrl 0xc020f4d8 <yosemite_setup_arch+188>: li r5,64 0xc020f4dc <yosemite_setup_arch+192>: mr r31,r3 0xc020f4e0 <yosemite_setup_arch+196>: lis r4,-4288 0xc020f4e4 <yosemite_setup_arch+200>: li r3,0 0xc020f4e8 <yosemite_setup_arch+204>: bl 0xc000c0f8 <ioremap64> End of assembler dump. (gdb)
Once again, we need not be PowerPC assembly language experts to understand what is happening here. Notice the labels associated with the PowerPC bl instruction. This is a function call in PowerPC mnemonics. The symbolic function labels are the important data points. After a cursory analysis, we see several function calls near the start of this assembler listing:
Address Function 0xc020f438 ocp_get_one_device() 0xc020f45c memcpy() 0xc020f474 ocp_get_one_device() 0xc020f48c memcpy() 0xc020f4ac ibm440gx_get_clocks()
Listing 14-9 reproduces portions of the source file yosemite.c. Correlating the functions we found in the gdb disassemble output, we see those labels occurring in the function yosemite_set_emacdata(), around the line numbers reported by gdb when the breakpoint at yosemite_setup_arch() was encountered. The key to understanding the anomaly is to notice the subroutine call at the very start of yosemite_setup_arch(). The compiler has inlined the call to yosemite_set_emacdata()instead of generating a function call, as would be expected by simple inspection of the source code. This inlining produced the mismatch in the line numbers when gdb hit the breakpoint. Even though the yosemite_set_emacdata() function was not declared using the inline keyword, GCC inlined the function as a performance optimization.
Listing 14-9
Portions of Source File yosemite.c
109 static void __init yosemite_set_emacdata(void)
110 {
111 struct ocp_def *def;
112 struct ocp_func_emac_data *emacdata;
113
114 /* Set mac_addr and phy mode for each EMAC */
115
116 def = ocp_get_one_device(OCP_VENDOR_IBM, OCP_FUNC_EMAC, 0);
117 emacdata = def->additions;
118 memcpy(emacdata->mac_addr, __res.bi_enetaddr, 6);
119 emacdata->phy_mode = PHY_MODE_RMII;
120
121 def = ocp_get_one_device(OCP_VENDOR_IBM, OCP_FUNC_EMAC, 1);
122 emacdata = def->additions;
123 memcpy(emacdata->mac_addr, __res.bi_enet1addr, 6);
124 emacdata->phy_mode = PHY_MODE_RMII;
125 }
126
...
304
305 static void __init
306 yosemite_setup_arch(void)
307 {
308 yosemite_set_emacdata();
309
310 ibm440gx_get_clocks(&clocks, YOSEMITE_SYSCLK, 6 * 1843200);
311 ocp_sys_info.opb_bus_freq = clocks.opb;
312
313 /* init to some ~sane value until calibrate_delay() runs */
314 loops_per_jiffy = 50000000/HZ;
315
316 /* Setup PCI host bridge */
317 yosemite_setup_hose();
318
319 #ifdef CONFIG_BLK_DEV_INITRD
320 if (initrd_start)
321 ROOT_DEV = Root_RAM0;
322 else
323 #endif
324 #ifdef CONFIG_ROOT_NFS
325 ROOT_DEV = Root_NFS;
326 #else
327 ROOT_DEV = Root_HDA1;
328 #endif
368 Chapter 14 â
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Sponsored by AMD
Built-in forensics, incident response, and security with Red Hat Enterprise Linux 6
Every security policy provides guidance and requirements for ensuring adequate protection of information and data, as well as high-level technical and administrative security requirements for a system in a given environment. Traditionally, providing security for a system focuses on the confidentiality of the information on it. However, protecting the data integrity and system and data availability is just as important. For example, when processing United States intelligence information, there are three attributes that require protection: confidentiality, integrity, and availability.
Learn more about catching the bad guy in this free white paper.
Sponsored by DLT Solutions
| Designing Electronics with Linux | May 22, 2013 |
| Dynamic DNS—an Object Lesson in Problem Solving | May 21, 2013 |
| Using Salt Stack and Vagrant for Drupal Development | May 20, 2013 |
| Making Linux and Android Get Along (It's Not as Hard as It Sounds) | May 16, 2013 |
| Drupal Is a Framework: Why Everyone Needs to Understand This | May 15, 2013 |
| Home, My Backup Data Center | May 13, 2013 |
- New Products
- Linux Systems Administrator
- Web & UI Developer (JavaScript & j Query)
- Senior Perl Developer
- Technical Support Rep
- UX Designer
- Large-Scale Mail with Postfix, OpenLDAP and Courier
- Open-Source Learning Management with Moodle
- Using an SMS Server to Provide a Robust Alerting Service for Nagios
- The ELF Object File Format by Dissection
Enter to Win an Adafruit Pi Cobbler Breakout Kit for Raspberry Pi

It's Raspberry Pi month at Linux Journal. Each week in May, Adafruit will be giving away a Pi-related prize to a lucky, randomly drawn LJ reader. Winners will be announced weekly.
Fill out the fields below to enter to win this week's prize-- a Pi Cobbler Breakout Kit for Raspberry Pi.
Congratulations to our winners so far:
- 5-8-13, Pi Starter Pack: Jack Davis
- 5-15-13, Pi Model B 512MB RAM: Patrick Dunn
- 5-21-13, Prototyping Pi Plate Kit: Philip Kirby
- Next winner announced on 5-27-13!
Featured Jobs
| Linux Systems Administrator | Houston and Austin, Texas | Host Gator |
| Senior Perl Developer | Austin, Texas | Host Gator |
| Technical Support Rep | Houston and Austin, Texas | Host Gator |
| UX Designer | Austin, Texas | Host Gator |
| Web & UI Developer (JavaScript & j Query) | Austin, Texas | Host Gator |
Free Webinar: Hadoop
How to Build an Optimal Hadoop Cluster to Store and Maintain Unlimited Amounts of Data Using Microservers
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Some of key questions to be discussed are:
- What is the “typical” Hadoop cluster and what should be installed on the different machine types?
- Why should you consider the typical workload patterns when making your hardware decisions?
- Are all microservers created equal for Hadoop deployments?
- How do I plan for expansion if I require more compute, memory, storage or networking?



8 hours 36 min ago
19 hours 17 min ago
1 day 1 hour ago
1 day 1 hour ago
1 day 3 hours ago
1 day 5 hours ago
1 day 12 hours ago
1 day 12 hours ago
1 day 14 hours ago
1 day 20 hours ago