Skip to content

4 Running Programs Under gdb

4.1 Compiling for Debugging

gcc, the gnu C/C++ compiler, supports ‘-g’ with or without ‘-O’, making it possible to debug optimized code. We recommend that you always use ‘-g’ whenever you compile a program. You may think your program is correct, but there is no sense in pushing your luck. For more information, see Chapter 11 [Optimized Code], page 159.

gdb knows about preprocessor macros and can show you their expansion (see Chapter 12 [Macros], page 163). Most compilers do not include information about preprocessor macros in the debugging information if you specify the ‘-g’ flag alone. Version 3.1 and later of gcc, the gnu C compiler, provides macro information if you are using the DWARF debugging format, and specify the option ‘-g3’.

NOTE: 上面这段话的意思是:在编译期的option中添加上-g3 -DWARF就可以包含macro的调试信息,比如:

gcc -g3  -DWARF

See Section “Options for Debugging Your Program or GCC” in Using the gnu Compiler Collection (GCC), for more information on gcc options affecting debug information.

You will have the best debugging experience if you use the latest version of the DWARF debugging format that your compiler supports. DWARF is currently the most expressive and best supported debugging format in gdb.

NOTE: 关于DWARF 是一种debugging format。

4.2 Starting your Program

run

r

4.3 Your Program’s Arguments

4.7 Debugging an Already-running Process

attach process-id

detach

4.9 Debugging Multiple Inferiors and Programs

gdb lets you run and debug multiple programs in a single session. In addition, gdb on some systems may let you run several programs simultaneously (otherwise you have to exit from one before starting another). In the most general case, you can have multiple threads of execution in each of multiple processes, launched from multiple executables.

inferior

gdb represents the state of each program execution with an object called an inferior. An inferior typically corresponds to a process, but is more general and applies also to targets that do not have processes. Inferiors may be created before a process runs, and may be retained after a process exits. Inferiors have unique identifiers that are different from process ids.

info inferiors

info inferiors

Print a list of all inferiors currently being managed by gdb.

To switch focus between inferiors, use the inferior command:

inferior infno

inferior infno

The debugger convenience variable ‘$_inferior’ contains the number of the current inferior. You may find this useful in writing breakpoint conditional expressions, command scripts, and so forth. See Section 10.11 [Convenience Variables], page 139, for general information on convenience variables.

add-inferior and clone-inferior

You can get multiple executables into a debugging session via the add-inferior and clone-inferior commands. On some systems gdb can add inferiors to the debug session automatically by following calls to fork and exec. To remove inferiors from the debugging session use the remove-inferiors command.

4.10 Debugging Programs with Multiple Threads

NOTE: 在下列章节中,也介绍了thread相关的主题:

current thread

The gdb thread debugging facility allows you to observe all threads while your program runs—but whenever gdb takes control, one thread in particular is always the focus of debugging. This thread is called the current thread. Debugging commands show program information from the perspective of the current thread.

NOTE: 从实践结果来看,如果是debug an already running process,则gdb默认是attach到main thread,即默认情况下current 他head是main thread。

systag

NOTE: “systag”的含义是system tag

Whenever gdb detects a new thread in your program, it displays the target system’s identification for the thread with a message in the form ‘[New systag]’, where systag is a thread identifier whose form varies depending on the particular system.

GDB per-inferior thread ID

For debugging purposes, gdb associates its own thread number —always a single integer—with each thread of an inferior. This number is unique between all threads of an inferior, but not unique between threads of different inferiors.

Qualified thread ID

You can refer to a given thread in an inferior using the qualified inferior-num.thread-num syntax, also known as qualified thread ID, with inferior-num being the inferior number and thread-num being the thread number of the given inferior. For example, thread 2.3 refers to thread number 3 of inferior 2. If you omit inferior-num (e.g., thread 3), then gdb infers you’re referring to a thread of the current inferior.

GDB Global thread ID

In addition to a per-inferior number, each thread is also assigned a unique global number, also known as global thread ID, a single integer.

$_thread and $_gthread

See Convenience Variables, for general information on convenience variables.

info threads

NOTE: 下面是我在 GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-110.el7 上使用此命令的输出

(gdb) info threads 
  Id   Target Id         Frame 
  5    Thread 0x7f7775589700 (LWP 81330) "main" 0x00007f777620ecf2 in pthread_cond_timedwait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0
  4    Thread 0x7f7774d88700 (LWP 81331) "main" 0x00007f77764de1ad in nanosleep () from /lib64/libc.so.6
  3    Thread 0x7f7774587700 (LWP 81332) "main" 0x00007f7776517923 in epoll_wait () from /lib64/libc.so.6
  2    Thread 0x7f7773d86700 (LWP 81333) "main" 0x00007f7776517923 in epoll_wait () from /lib64/libc.so.6
* 1    Thread 0x7f77777cf780 (LWP 81329) "main" 0x00007f77764de1ad in nanosleep () from /lib64/libc.so.6

An asterisk ‘*’ to the left of the GDB thread number indicates the current thread.

thread apply

4.11 Debugging Forks

On most systems, gdb has no special support for debugging programs which create additional processes using the fork function. When a program forks, gdb will continue to debug the parent process and the child process will run unimpeded(未受阻的). If you have set a breakpoint in any code which the child then executes, the child will get a SIGTRAP signal which (unless it catches the signal) will cause it to terminate.

NOTE: 默认是调试parent process,即默认情况下,gdb是attach parent process的。那如何让gdb attach到child process呢?下面对此进行了介绍:

However, if you want to debug the child process there is a workaround which isn’t too painful. Put a call to sleep in the code which the child process executes after the fork. It may be useful to sleep only if a certain environment variable is set, or a certain file exists, so that the delay need not occur when you don’t want to run gdb on the child. While the child is sleeping, use the ps program to get its process ID. Then tell gdb (a new invocation of gdb if you are also debugging the parent process) to attach to the child process (see Section 4.7 [Attach], page 32). From that point on you can debug the child process just like any other process which you attached to.

On some systems, gdb provides support for debugging programs that create additional processes using the fork or vfork functions. On gnu/Linux platforms, this feature is supported with kernel version 2.5.46 and later.

By default, when a program forks, gdb will continue to debug the parent process and the child process will run unimpeded.

set follow-fork-mode

If you want to follow the child process instead of the parent process, use the command set follow-fork-mode

set follow-fork-mode mode

  • parent
  • child

show follow-fork-mode

set detach-on-fork

On Linux, if you want to debug both the parent and child processes, use the command set detach-on-fork.

set detach-on-fork mode

  • on
  • off

show detach-on-fork