G++ is the C++ compiler under Unix/Linux, and gdb is a powerful debugging tool under Unix/Linux. Most of the time, the C/C++ code we write does not run on Windows but on a Linux system. Here I record some usage of g++ and gdb in case they are needed.
Using g++
When g++ performs compilation work, it needs 4 steps in total:
- Preprocessing, generating a .i file, mainly expanding header files and macro definitions:
g++ -E test.cpp -o test.i - Compilation, converting the preprocessed file into assembly language and generating a .s file:
g++ -S test.i -o test.s - Assembly, turning the assembly into object code (machine code) and generating a .o file, mainly converting the .s file into a binary file:
g++ -c test.s -o test.o - Linking, linking the object code to generate an executable program:
g++ test.o -o test
The steps above can also be done with a single command:
g++ test.cpp -o test
When compiling multiple files, there are two approaches:
$ g++ a.cpp b.cpp c.cpp -o test #compile all files at once
$ g++ a.cpp -o a.o #compile separately
$ g++ b.cpp -o b.o
$ g++ c.cpp -o c.o
$ g++ a.o b.o c.o -o test
Here the separate compilation approach is recommended, since when you modify one or more of the files you only need to compile that file or those files, rather than compiling from scratch.
Commonly used g++ options:
| Command | Description |
|---|---|
| -Wall | Output some warning and error messages during compilation |
| -c | Compile only, do not link |
| -E | Preprocess the source file |
| -S | Convert the preprocessed file into an assembly file |
| -o | Specify the output file name |
| -I | Specify a path containing header files |
| -l | Specify an additional library |
| -L | Specify an additional library path |
| -shared | Generate a dynamic library file |
Under Linux the file type does not depend on the suffix, but generally speaking:
.o is an object file, equivalent to a .obj file in windows
.so is a shared library, that is, a shared object used for dynamic linking, roughly the same as .dll
.a is a static library, several .o files combined together, used for static linking
.la are some shared libraries automatically generated by libtool, mainly recording some configuration information.
Using gdb
The .cpp must be compiled with the -g option for the generated executable to be debuggable at source level with gdb
g++ -g test.cpp -o test
It is worth noting that -g has 4 levels:
- g0 is the same as not adding -g. That is, no information is included
- g1 includes only minimal information; generally it is used only when you do not need to debug but only need backtrace information, and you really care about program size or have some other confidentiality/special requirement.
- g2 is the gdb default level and includes most of the information you need.
- g3 includes some extra information, for example macro definition information. When you need to debug macro definitions, use -g3
Generally speaking, gdb mainly helps you accomplish the following four things:
Start the program, and run the program according to your own requirements.
Let the debugged program stop at a breakpoint at a specified position.
When the program stops, inspect what is happening in the program at that moment.
Dynamically change the execution environment of the program.
Several ways to run a program under gdb:
gdb ${program}then, after entering gdb, typerun(short form r) ${arg1} ${arg2} … ${argN}gdb --args ${program} ${arg1} ${arg2} … ${argN}, then after entering gdb runrun- After entering gdb, type
file ${program}. Then useset args ${arg1} ${arg2} … ${argN}to set the program arguments, and then runrun
Commonly used gdb debugging commands:
| Command | Description |
|---|---|
| start | Start executing the program and stop before the first statement of the main function |
| backtrace/bt | View the function calls at each level and display the stack information |
| step/s | Single-step debugging, stepping into the current function |
| next/n | Single-step debugging, stepping over the current function |
| until/u | Execute until the current loop is finished |
| continue/c | Continue running the program |
| finish | Execute until the current function returns |
| list/l | List the source code, 10 lines at a time |
| list <line number> | List the source code starting from the given line |
| list <function name> | List the source code of the function |
| print/p <expression> | Print the value of the expression |
| frame/f x | Switch to frame x, where x is shown in the bt command, starting from 0, with 0 meaning the top of the stack |
| up/down x | Move x frames towards the top/bottom of the stack; when x is not given it defaults to 1 |
| info/i locals | Print the local variables of the current stack frame |
| set var x | Modify the value of the current variable x |
| break <line number> | Set a breakpoint at the specified line of a source file |
| break <function name> | Set a breakpoint at the specified function of a source file |
| break <line number/function name> if <condition> | Set a conditional breakpoint; when the condition is met the program breaks at the location |
| watch <variable> | Write watch on the specified variable; when the variable changes the program stops running |
| rwatch <variable> | Read watch on the specified variable; when the variable is read the program stops running |
| awatch <variable> | Read/write watch on the specified variable; the program stops running when the variable changes or is read |
| delete <line number/function name> | Delete a breakpoint |
| info/i b | View breakpoint information |
| save breakpoint <file name>.dp | Save the breakpoints into the specified file |
| -x <file name>.dp | This option reads the specified file and restores the breakpoint settings in it |
| quit | Quit gdb debugging |
Reference
Xi Shan Ju Shi who loves tinkering — a series on commonly used GDB commands
chenyu who is changing himself — a summary of basic gdb debugging commands and usage under linux
Getting started with gdb debugging, a high-quality guide written by an expert