<jupyter_start><jupyter_text>Debugging C Programs with GDB* <NAME>,<NAME>: C in a Nutshell(Second Edition),O’Reilly Media, Inc. 2016> **C11**: The present description of `the C language is based on the 2011 international C standard`,ISO/IEC 9899:2011An important part of software development is testing and troubleshooting.In a large program, programming errors — or **bugs** — are practically inevitable. Programs can deliver wrong results, get hung up in infinite loops, or crash due to illegal memory operations. The task of finding and eliminating such errors is called **debugging** a program.Many bugs are not apparent by simply **studying the source code**.Extra output provided by a testing version of the program is one helpful diagnostic technique. You can **add statements to display the contents** of variables and other information during runtime.However, you can generally perform runtime diagnostics much more efficiently by using a **debugger.**A **debugger** is a program that runs another program in a finely **controlled** environment. For example, a debugger allows you to run the program `step by step`, `observing the contents` of  variables, `memory locations`, and `CPU registers（寄存器)` after each statement.You can also analyze the sequence of function calls that lead to a given point in the program.This chapter is an introduction to one powerful and widely used debugger, the **GNU debugger (GDB)**. The sections that follow describe GDB’s basic options and commands. Installing GDBIf the GNU C compiler, GCC, is available on your system, then GDB is probably **already** installed as well. You can tell by running the following command, which displays the debugger’s version and copyright information:<jupyter_code>!gdb --version<jupyter_output>GNU gdb (GDB) 8.1
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-w64-mingw32".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word".<jupyter_text>A Sample Debugging SessionThis section describes a sample GDB session to illustrate the basic operation of the debugger.Many problems in C programs can be pinpointed using just a handful of debugger commands. The program `gdb_example.c`, contains a logical error. We’ll use this program in the following subsections to show how GDB can be usedto track down such errors.<jupyter_code>%%file ./demo/src/gdb_example.c
// -------------------------------------------------------------
// A program to be debugged in a GDB session
//     gdb_example.c:
// Test the swap() function, which exchanges the contents of two int variables.
// -------------------------------------------------------------

#include <stdio.h>
void swap( int *p1, int *p2 ); // Exchange *p1 and *p2

int main()
{
    int a = 10, b = 20;
    /* ... */
    printf( "The old values: a = %d; b = %d.\n", a, b );
    swap( &a, &b );
    printf( "The new values: a = %d; b = %d.\n", a, b );
    /* ... */
    return 0;
}

void swap(int *p1, int *p2) // Exchange *p1 and *p2
{
    int *p = p1;
    p1 = p2;
    p2 = p;
}<jupyter_output><empty_output><jupyter_text>Symbol InformationGDB is a **symbolic** command-line debugger. **Symbolic** here means that you can refer to `variables and functions` in the **running** program by the `names` you gave them in your **C** source code. In order to display and interpret these names, the **debugger**  requires  **information** about the types of the variables and functions in the program, and about which instructions in the **executable file** correspond to which lines in the source files. Such information takes the form of a **symbol table**(符号表）, which the compiler and linker **in the executable file** when you run GCC with the **`-g`** option.In a large program consisting of several source files, you **must compile each module with the `-g` option.**>**Compiling for debugging** >>Normally, an executable file does not contain any references to the original program source code, such as variable names or line-numbers—the executable file is simply the sequence of machine code instructions produced by the compiler. This is insufficient for debugging, since there is no easy way to find the cause of an error if the program crashes.>>GCC provides the **`-g`** debug option to store additional debugging information in object files and executables. This debugging information allows errors to be traced back from a specific machine instruction to the corresponding line in the original source file. It also allows the execution of a program to be traced in a debugger, such as the GNU Debugger gdb The default  executable file: `a.exe`(Windows),`a.out`(Linux)```gcc  *.c```<jupyter_code>!gcc ./demo/src/gdb_example.c
!.\a.exe<jupyter_output>The old values: a = 10; b = 20.
The new values: a = 10; b = 20.<jupyter_text>Compiling for debugging: the executable file with symbol table<jupyter_code>!gcc -g ./demo/src/gdb_example.c
!dir a.*<jupyter_output><empty_output><jupyter_text>Finding a BugThe following command runs the program from `./demo/src/gdb_example.c`<jupyter_code>!.\a.exe<jupyter_output>The old values: a = 10; b = 20.
The new values: a = 10; b = 20.<jupyter_text>The program produces the following output:```    The old values: a = 10; b = 20.The new values: a = 10; b = 20.```Although the **swap()** function call is `plain` to see in the source code, the contents of the variables `a and b have not been swapped`. We can look for the reason using **GDB**.   start GDBTo begin the debugging session, start **GDB** from the shell, specifying the name of the executable file as a command-line argument to the debugger.```>gdb a.exe```The **debugger** loads the program executable but **waits** for your instructions before running it. GDB prints **(gdb)** at the beginning of a new line to **prompt** you for a debugging command.![gdb](./img/gdb.jpg)  listYou can start by entering the command **list**, or just its initial **l** for short, to **list a few lines of source code** of the program you are debugging. By default, the listing shows 10 lines, centered on the source line that is ready to be executed next. In our example, the program has just been started, and the next line is line 10, where the function **main()** begins:![gdb-list](./img/gdb-list.jpg)If you follow one **list** command with another, **GDB** prints the next few lines of source code.![gdb-list](./img/gdb-list-list.jpg) breakpointBefore you instruct GDB to run the program, you should tell it **where you want it to stop**. You can do this by setting a **breakpoint**. When the debugger reaches the breakpoint, it interrupts the execution of your program* giving you an opportunity to examine the program’s state at that point.* you can continue execution line by line, observing the state of program objects as you go.To set a breakpoint, enter the command **break**, or `b` for short. Breakpoints are usually set at a **specific** line of source code or at the **beginning** of a function.The following command sets a breakpoint at line 15 of the current source file, which is the line containing the **swap()** function call:![gdb-breakpoint](./img/gdb-breakpoint.jpg) runThe command **run**, or `r`, starts the program:![gdb-run](./img/gdb-run.jpg)Upon reaching the `breakpoint`, the debugger **interrupts*8 the execution of the program and **displays the line** containing the next statement to be executed.Because we suspect the bug in our example is in the **swap()** function, we want to execute that function **step by step.** stepGDB provides the commands `next`, or `n`, and `step`, or `s`.The `next` and `step` commands behave differently if the next line to be executed **contains** a function call.The `next` command executes the next line, **including** all function calls, and interrupts the program again at the following line.The `step` command, on the other hand, executes a **jump** to the function called in the line, provided that the debugging symbols are available for that function, and interrupts the program again at the **first statement in the function** body.In our example session, the command `step` takes us to the first statement in the **swap()** function:![gdb-s](./img/gdb-s.jpg)The debugger displays the values of the function arguments (here, these are the addresses of the variables `a` and `b`), and once again the next line to be executed. At this point, we can **check** to see whether **the values of the variables** referenced by the function’s pointer arguments are correct. printWe can do this using the **print** command (`p` for short), which displays the value of a given expression:![gdb-p](./img/gdb-p.jpg)The expression `*p1` has the value `10`, and `*p2` has the value `20`. The output of GDB’s `print` command has the form `$number = value`, where `$number` is a GDB variable that the debugger creates so that you can refer to this result later.  nextIf we now type n (for next) three times, the debugger executes lines 23, 24, and 25:![gdb-n](./img/gdb-n.jpg)As long as the program flow **has not yet returned from the swap()** function to `main(`), we can use the `print` command to display the contents of the local variables![gdb-np](./img/gdb-np.jpg)Now `*p1` has the value `20`, and `*p2` has the value `10`, which **seems** correct. We can continue the examination of the program state with two more **print** commands![gdb-npp](./img/gdb-npp.jpg)As these `print` commands show, the values of the **pointers** `p1` and `p2` have been swapped — not the **contents** of the memory locations referenced as `*p1` and `*p2`. ![gdb-s](./img/gdb-s.jpg)That was the bug in **swap()**The function needs to be amended so that it exchanges the int **values** addressed as `*p1` and `*p2`, rather than the **pointer values** stored in `p1` and `p2`. A correct version would be the following:```cvoid swap( int *p1, int *p2 ) // Exchange *p1 and *p2{    int tmp = *p1;    *p1 = *p2;    *p2 = tmp;}``` continueThe command `continue`, abbreviated `c`, lets program execution continue until it reaches the next breakpoint or the end of the program:![gdb-c](./img/gdb-c.jpg) quitAs the `(gdb)` prompt indicates, the debugger is still **running**. To stop it, enter the command `quit` or `q`. ![gdb-q](./img/gdb-q.jpg)The `quit` command terminates the debugger even if the program you are debugging is still running. However, GDB does prompt you for confirmation in this case:<jupyter_code>%%file ./demo/src/gdb_example_correct.c
// -------------------------------------------------------------
// A program to be debugged in a GDB session
//     gdb_example.c:
// Test the swap() function, which exchanges the contents of two int variables.
// -------------------------------------------------------------

#include <stdio.h>
void swap( int *p1, int *p2 ); // Exchange *p1 and *p2

int main()
{
    int a = 10, b = 20;
    /* ... */
    printf( "The old values: a = %d; b = %d.\n", a, b );
    swap( &a, &b );
    printf( "The new values: a = %d; b = %d.\n", a, b );
    /* ... */
    return 0;
}

void swap(int *p1, int *p2) // Exchange *p1 and *p2
{
    //int *p = p1;
    //p1 = p2;
   //p2 = p;
    
    int tmp = *p1;
    *p1 = *p2;
    *p2 = tmp;
}
!gcc ./demo/src/gdb_example_correct.c
!dir a.*
!.\a.exe<jupyter_output>The old values: a = 10; b = 20.
The new values: a = 20; b = 10.
{'fraction_non_alphanumeric': 0.12534842469803192, 'fraction_numerical': 0.012247656052031422, 'mean_word_length': 3.840556009811938, 'pattern_counts': {'":': 0, '<': 28, '<?xml version=': 0, '>': 35, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '6', 'dir': 'jupyter-structured-clean-dedup', 'id': '605968', 'license': 'MIT', 'n_tokens_mistral': 3442, 'n_tokens_neox': 3266, 'n_words': 1678, 'path': 'notebook/Unit8-5-Debugging_C_Programs_with_GDB.ipynb', 'repo_name': 'marketmodelbrokendown/1', 'size': '11851'}