9.4 Multiprocessor Performance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 501
9.4.1 Types of SMP Hardware . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 501
9.4.2 Programming on an SMP Machine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 506
9.5 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 509
9.5.1 Performance Issues in This Chapter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 510
9.5.2 Terms Introduced in This Chapter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 510
9.5.3 Tools Used in This Chapter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 510
9.5.4 Online Resources . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 511
9.5.5 References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 511
Chapter 10 Debugging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 513
10.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 513
10.2 The Most Basic Debugging Tool: printf . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 514
10.2.1 Problems with Using printf . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 514
10.2.2 Using printf Effectively . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 519
10.2.3 Some Final Words on printf Debugging . . . . . . . . . . . . . . . . . . . . . . . . . . . 528
10.3 Getting Comfortable with the GNU Debugger: gdb . . . . . . . . . . . . . . . . . . . . . 529
10.3.1 Running Your Code with gdb . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 530
10.3.2 Stopping and Restarting Execution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 531
10.3.3 Inspecting and Manipulating Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 541
10.3.4 Attaching to a Running Process with gdb . . . . . . . . . . . . . . . . . . . . . . . . . 553
10.3.5 Debugging Core Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 553
10.3.6 Debugging Multithreaded Programs with gdb . . . . . . . . . . . . . . . . . . . . . . 557
10.3.7 Debugging Optimized Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 558
10.4 Debugging Shared Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 561
10.4.1 When and Why to Use Shared Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . 562
10.4.2 Creating Shared Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 563
10.4.3 Locating Shared Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 564
10.4.4 Overriding the Default Shared Object Locations . . . . . . . . . . . . . . . . . . . . 564
10.4.5 Security Issues with Shared Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 565
10.4.6 Tools for Working with Shared Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . 565
10.5 Looking for Memory Issues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 569
10.5.1 Double Free . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 569
10.5.2 Memory Leaks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 570
10.5.3 Buffer Overflows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 570
10.5.4 glibc Tools . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 572
10.5.5 Using Valgrind to Debug Memory Issues . . . . . . . . . . . . . . . . . . . . . . . . . . 576
10.5.6 Looking for Overflows with Electric Fence . . . . . . . . . . . . . . . . . . . . . . . . 581
Contents xv