代码调试篇(1):零基础快速掌握 gdb 常用命令

Author: stormQ

Created: Monday, 25. February 2019 10:31PM

Last Modified: Monday, 26. October 2020 10:30AM



摘要

本文描述了:1)启动调试进程的多种方式,从而提高调试效率;2)调试进程必须掌握的命令;3)如何使用 gdb 日志功能记录调试过程;4)其他常用命令。

启动 gdb


启动一个不带参数的进程

命令:

# executable-file 为可执行文件的路径
$ gdb <executable-file>

示例:

# 启动一个不带参数的可执行程序 main,位于./samples目录下
$ gdb ./samples/main

返回上一级


启动一个带参数的进程

命令:

# executable-file 为可执行文件的路径
# arg1 为可执行文件的第一个参数
# argn 为可执行文件的第n个参数
$ gdb --args <executable-file> <arg1> <argn>

示例:

# 启动一个带参数的可执行程序 main,位于./samples目录下
# 假设程序参数只有一个,为配置文件 ./config.txt
$ gdb --args ./samples/main ./config.txt

返回上一级


调试一个正在运行的进程

命令:

$ gdb
# process-id为要调试进程的进程ID
(gdb) attach <process-id>

示例:

$ gdb
# 假设要调试进程的进程ID为8888
(gdb) attach 8888

返回上一级


使用命令文件调试进程

命令:

# command-file为存放gdb命令的文件
# 为了便于区分,该文件使用.gdb结尾(当然也可以使用其他格式结尾,比如:.txt)
$ gdb -x <command-file>

示例:

$ gdb -x main.gdb

假设 main.gdb 文件的内容为:

# 指定可执行文件的路径
file ./samples/main
# 设置可执行文件的参数(如果有的话)
set args ./config.txt
# 启动进程
start
# 继续执行
c

返回上一级


调试进程


查看进程信息

命令:

# info命名可缩写为i
(gdb) info proc

示例:

(gdb) i proc 
process 11356
cmdline = '/home/tmp/b_Og'
cwd = '/home/tmp'
exe = '/home/tmp/b_Og'

从输出结果中可以看出,进程ID为 11356,进程启动项为 /home/tmp/b_Og,当前目录(即启动gdb时所在的目录)为 /home/tmp,可执行程序为 /home/tmp/b_Og。

命令:

(gdb) i threads

示例:

(gdb) i threads 
  Id   Target Id         Frame 
1    Thread 0x7ffff7fce740 (LWP 1549"main" 0x00007ffff7626c1d in nanosleep ()
    at ../sysdeps/unix/syscall-template.S:84
  2    Thread 0x7ffff6f42700 (LWP 1553"main" 0x00007ffff7626c1d in nanosleep ()
    at ../sysdeps/unix/syscall-template.S:84

打印结果中Id列左侧带*的为当前线程,ID列为 gdb 自定义的线程ID,Target Id为真实的线程ID(这里有两个线程,线程ID分别为:1549、1553),Frame为线程的当前帧(包含:线程运行到什么位置了等信息)。

命令:

(gdb) p $_thread

示例:

(gdb) p $_thread
$1 = 1

注意: 打印结果所显示的线程ID(这里是1)是 gdb 内部自定义的(即i threads命令输出结果中最左侧的Id列的值),而不是真实的线程ID。

返回上一级


查看堆栈信息

命令:

# 只打印堆栈信息的调用层次
(gdb) bt
# 打印堆栈信息的调用层次,并打印函数参数和局部变量的值
(gdb) bt full

示例:

(gdb) bt
#0  0x00007ffff7626c1d in nanosleep () at ../sysdeps/unix/syscall-template.S:84
#1  0x0000000000401633 in std::this_thread::sleep_for<double, std::ratio<1l, 1000l> > (
    __rtime=...) at /usr/include/c++/6/thread:323
#2  0x00000000004010ad in main () at main.cpp:11
(gdb) bt full
#0  0x00007ffff7626c1d in nanosleep () at ../sysdeps/unix/syscall-template.S:84
No locals.
#1  0x0000000000401633 in std::this_thread::sleep_for<double, std::ratio<1l, 1000l> > (
    __rtime=...) at /usr/include/c++/6/thread:323
        __s = {__r = 0}
        __ns = {__r = 10000000}
        __ts = {tv_sec = 0, tv_nsec = 7543688}
#2  0x00000000004010ad in main () at main.cpp:11
No locals.

命令:

# 只打印堆栈信息的调用层次
(gdb) thread apply all bt

# 只打印堆栈信息的调用层次
(gdb) thread apply all where

示例:

(gdb) thread apply all bt

Thread 2 (Thread 0x7ffff6f42700 (LWP 1553)):
#0  0x00007ffff7626c1d in nanosleep () at ../sysdeps/unix/syscall-template.S:84
#1  0x0000000000401633 in std::this_thread::sleep_for<double, std::ratio<1l, 1000l> > (
    __rtime=...) at /usr/include/c++/6/thread:323
#2  0x00000000004019d7 in ShmManager::threadFunc (this=0x61fc20) at shm_manager_sim.cpp:49
#3  0x0000000000401841 in ShmManager::<lambda()>::operator()(void) const (
    __closure=0x61fc68) at shm_manager_sim.cpp:28
#4  0x0000000000401e74 in std::_Bind_simple<ShmManager::start()::<lambda()>()>::_M_invoke<>(std::_Index_tuple<>) (this=0x61fc68) at /usr/include/c++/6/functional:1391
#5  0x0000000000401dfe in std::_Bind_simple<ShmManager::start()::<lambda()>()>::operator()(void) (this=0x61fc68) at /usr/include/c++/6/functional:1380
#6  0x0000000000401dce in std::thread::_State_impl<std::_Bind_simple<ShmManager::start()::<lambda()>()> >::_M_run(void) (this=0x61fc60) at /usr/include/c++/6/thread:197
#7  0x00007ffff7b0857f in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#8  0x00007ffff761d6ba in start_thread (arg=0x7ffff6f42700) at pthread_create.c:333
#9  0x00007ffff735341d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:109

Thread 1 (Thread 0x7ffff7fce740 (LWP 1549)):
#0  0x00007ffff7626c1d in nanosleep () at ../sysdeps/unix/syscall-template.S:84
#1  0x0000000000401633 in std::this_thread::sleep_for<double, std::ratio<1l, 1000l> > (
    __rtime=...) at /usr/include/c++/6/thread:323
#2  0x00000000004010ad in main () at main.cpp:11
(gdb) thread apply all where

Thread 2 (Thread 0x7ffff6f42700 (LWP 1553)):
#0  0x00007ffff7626c1d in nanosleep () at ../sysdeps/unix/syscall-template.S:84
#1  0x0000000000401633 in std::this_thread::sleep_for<double, std::ratio<1l, 1000l> > (
    __rtime=...) at /usr/include/c++/6/thread:323
#2  0x00000000004019d7 in ShmManager::threadFunc (this=0x61fc20) at shm_manager_sim.cpp:49
#3  0x0000000000401841 in ShmManager::<lambda()>::operator()(void) const (
    __closure=0x61fc68) at shm_manager_sim.cpp:28
#4  0x0000000000401e74 in std::_Bind_simple<ShmManager::start()::<lambda()>()>::_M_invoke<>(std::_Index_tuple<>) (this=0x61fc68) at /usr/include/c++/6/functional:1391
#5  0x0000000000401dfe in std::_Bind_simple<ShmManager::start()::<lambda()>()>::operator()(void) (this=0x61fc68) at /usr/include/c++/6/functional:1380
#6  0x0000000000401dce in std::thread::_State_impl<std::_Bind_simple<ShmManager::start()::<lambda()>()> >::_M_run(void) (this=0x61fc60) at /usr/include/c++/6/thread:197
#7  0x00007ffff7b0857f in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#8  0x00007ffff761d6ba in start_thread (arg=0x7ffff6f42700) at pthread_create.c:333
#9  0x00007ffff735341d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:109

Thread 1 (Thread 0x7ffff7fce740 (LWP 1549)):
#0  0x00007ffff7626c1d in nanosleep () at ../sysdeps/unix/syscall-template.S:84
#1  0x0000000000401633 in std::this_thread::sleep_for<double, std::ratio<1l, 1000l> > (
    __rtime=...) at /usr/include/c++/6/thread:323
#2  0x00000000004010ad in main () at main.cpp:11

命令:

# 先切换到指定线程,线程ID为gdb自定义的
(gdb) thread <thread-id-by-gdb>
# 只打印堆栈信息的调用层次
(gdb) bt

示例:

(gdb) thread 2
[Switching to thread 2 (Thread 0x7ffff6f42700 (LWP 1553))]
#0  0x00007ffff7626c1d in nanosleep () at ../sysdeps/unix/syscall-template.S:84
84    in ../sysdeps/unix/syscall-template.S
(gdb) bt
#0  0x00007ffff7626c1d in nanosleep () at ../sysdeps/unix/syscall-template.S:84
#1  0x0000000000401633 in std::this_thread::sleep_for<double, std::ratio<1l, 1000l> > (
    __rtime=...) at /usr/include/c++/6/thread:323
#2  0x00000000004019d7 in ShmManager::threadFunc (this=0x61fc20) at shm_manager_sim.cpp:49
#3  0x0000000000401841 in ShmManager::<lambda()>::operator()(void) const (
    __closure=0x61fc68) at shm_manager_sim.cpp:28
#4  0x0000000000401e74 in std::_Bind_simple<ShmManager::start()::<lambda()>()>::_M_invoke<>(std::_Index_tuple<>) (this=0x61fc68) at /usr/include/c++/6/functional:1391
#5  0x0000000000401dfe in std::_Bind_simple<ShmManager::start()::<lambda()>()>::operator()(void) (this=0x61fc68) at /usr/include/c++/6/functional:1380
#6  0x0000000000401dce in std::thread::_State_impl<std::_Bind_simple<ShmManager::start()::<lambda()>()> >::_M_run(void) (this=0x61fc60) at /usr/include/c++/6/thread:197
#7  0x00007ffff7b0857f in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#8  0x00007ffff761d6ba in start_thread (arg=0x7ffff6f42700) at pthread_create.c:333
#9  0x00007ffff735341d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:109

返回上一级


查看/设置源码的搜索路径

命令:

(gdb) show directories

示例:

(gdb) show directories 
Source directories searched: $cdir:$cwd

命令:

# source-code-path 为要添加的源码搜索路径
(gdb) directory <source-code-path>

示例:

# 添加源码搜索路径为 /usr/include/boost/
(gdb) directory /usr/include/boost/
Source directories searched: /usr/include/boost:$cdir:$cwd

命令:

(gdb) directory

示例:

(gdb) directory
Reinitialize source path to empty? (y or n) y
Source directories searched: $cdir:$cwd

返回上一级


查看源码/汇编

注意: 要查看源码,需要在编译时带-g选项。

命令:

(gdb) list <line-number>

示例:

(gdb) list 1
warning: Source file is more recent than executable.
1    #include "shm_manager_sim.h"
2    #include "topic_manager_sim.h"
3    
4    int main()
5    
{
6        TopicManager::instance();
7    
8        ShmManager::instance()->start();
9    
10        while(true)

命令:

(gdb) list <file-name>:<line-number>

示例:

(gdb) list shm_manager_sim.h:10
5    #include <thread>
6    
7    class ShmManager;
8    typedef std::shared_ptr<ShmManager> ShmManagerPtr;
9    
10    class ShmManager
11    {

12    public:
13        static const ShmManagerPtr& instance();
14        void start();

命令:

# 上翻源码
(gdb) list -
# 下翻源码
(gdb) list

示例:

(gdb) list shm_manager_sim.h:10
5    #include <thread>
6    
7    class ShmManager;
8    typedef std::shared_ptr<ShmManager> ShmManagerPtr;
9    
10    class ShmManager
11    {

12    public:
13        static const ShmManagerPtr& instance();
14        void start();
(gdb) list -
1    #ifndef ROS_SHM_MANAGER_H
2    #define ROS_SHM_MANAGER_H
3    
4    #include <memory>
(gdb) list
5    #include <thread>
6    
7    class ShmManager;
8    typedef std::shared_ptr<ShmManager> ShmManagerPtr;
9    
10    class ShmManager
11    {

12    public:
13        static const ShmManagerPtr& instance();
14        void start();

命令:

# 只打印汇编代码
(gdb) disas <function-name>
# 打印汇编代码和对应的源码
(gdb) disas /m <function-name>

示例:

(gdb) disas main
Dump of assembler code for function main():
   0x0000000000401046 <+0>:    push   %rbp
   0x0000000000401047 <+1>:    mov    %rsp,%rbp
   0x000000000040104a <+4>:    sub    $0x20,%rsp
   0x000000000040104e <+8>:    mov    %fs:0x28,%rax
   0x0000000000401057 <+17>:    mov    %rax,-0x8(%rbp)
   0x000000000040105b <+21>:    xor    %eax,%eax
   0x000000000040105d <+23>:    callq  0x405248 <TopicManager::instance()>
   0x0000000000401062 <+28>:    callq  0x401776 <ShmManager::instance()>
   0x0000000000401067 <+33>:    mov    %rax,%rdi
   0x000000000040106a <+36>:    callq  0x401172 <std::__shared_ptr<ShmManager, (__gnu_cxx::_Lock_policy)2>::operator->()
   const>
   0x000000000040106f <+41>:    mov    %rax,%rdi
   0x0000000000401072 <+44>:    callq  0x40184a <ShmManager::start()>
...
(gdb) disas /m main
Dump of assembler code for function main():
5    {
   0x0000000000401046 <+0>:    push   %rbp
   0x0000000000401047 <+1>:    mov    %rsp,%rbp
   0x000000000040104a <+4>:    sub    $0x20,%rsp
   0x000000000040104e <+8>:    mov    %fs:0x28,%rax
   0x0000000000401057 <+17>:    mov    %rax,-0x8(%rbp)
   0x000000000040105b <+21>:    xor    %eax,%eax

6        TopicManager::instance();
   0x000000000040105d <+23>:    callq  0x405248 <TopicManager::instance()>

7    
8        ShmManager::instance()->start();
   0x0000000000401062 <+28>:    callq  0x401776 <ShmManager::instance()>
   0x0000000000401067 <+33>:    mov    %rax,%rdi
   0x000000000040106a <+36>:    callq  0x401172 <std::__shared_ptr<ShmManager, (__gnu_cxx::_Lock_policy)2>::operator->() const>
   0x000000000040106f <+41>:    mov    %rax,%rdi
   0x0000000000401072 <+44>:    callq  0x40184a <ShmManager::start()>
...

返回上一级


查看/设置/调试断点

命令:

(gdb) b <file-name>:<line-number>

示例:

(gdbb main.cpp:13
Breakpoint 2 at 0x40108cfile main.cppline 13.

命令:

(gdb) b <file-name>:<line-number> thread <thread-id-by-gdb>

示例:

(gdbb main.cpp:13 thread 1
Breakpoint 5 at 0x40108cfile main.cppline 13.

命令:

(gdb) b *<address>

示例:

(gdbb *0x00000000004010a1
Breakpoint 7 at 0x4010a1file main.cppline 13.

命令:

(gdb) b <file-name>:<line-number> if <expresion>

示例:

(gdbb main.cpp:14 if TopicManager::instance()->getNumSubscriptions() > 1000
Breakpoint 6 at 0x4010b2file main.cppline 14.
(gdbi breakpoints 
Num     Type           Disp Enb Address            What
5       breakpoint     keep y   0x000000000040108c in main() at main.cpp:13 thread 1
    stop only in thread 1
6       breakpoint     keep y   0x00000000004010b2 in main() at main.cpp:14
    stop only if TopicManager::instance()->getNumSubscriptions() > 1000

命令:

(gdb) i breakpoints

示例:

(gdbi breakpoints 
Num     Type           Disp Enb Address            What
2       breakpoint     keep y   0x000000000040108c in main() at main.cpp:13
3       breakpoint     keep y   0x000000000040105d in main() at main.cpp:6

命令:

(gdb) i breakpoints <breakpoint-number>

示例:

(gdbi breakpoints 2
Num     Type           Disp Enb Address            What
2       breakpoint     keep y   0x000000000040108c in main() at main.cpp:13

命令:

(gdb) i breakpoints <breakpoint-number>-<breakpoint-number>

示例:

(gdbi breakpoints 2-3
Num     Type           Disp Enb Address            What
2       breakpoint     keep y   0x000000000040108c in main() at main.cpp:13
3       breakpoint     keep y   0x000000000040105d in main() at main.cpp:6

命令:

(gdb) d

示例:

(gdb) d
Delete all breakpoints? (y or n) y
(gdb) i breakpoints 
No breakpoints or watchpoints.

命令:

(gdb) d breakpoints <breakpoint-number>

示例:

(gdbi breakpoints 
Num     Type           Disp Enb Address            What
4       breakpoint     keep y   0x000000000040108c in main() at main.cpp:16
5       breakpoint     keep y   0x000000000040105d in main() at main.cpp:8
(gdbd breakpoints 4
(gdbi breakpoints 
Num     Type           Disp Enb Address            What
5       breakpoint     keep y   0x000000000040105d in main() at main.cpp:8

命令:

(gdb) d breakpoints <breakpoint-number>-<breakpoint-number>

示例:

(gdb) i breakpoints 
Num     Type           Disp Enb Address            What
5       breakpoint     keep y   0x000000000040108c in main() at main.cpp:13 thread 1
    stop only in thread 1
6       breakpoint     keep y   0x00000000004010b2 in main() at main.cpp:14
    stop only if TopicManager::instance()->getNumSubscriptions() > 1000
(gdb) d 5-6
(gdb) i breakpoints 
No breakpoints or watchpoints.

命令:

# next命令可缩写为n
(gdb) next

示例:

(gdb) l
4    L_Subscription getAllSubscription();
5    
6    TopicManagerPtr g_topic_manager;
7    std::mutex g_topic_manager_mutex;
8    const TopicManagerPtr& TopicManager::instance()
9    {
10        if (!g_topic_manager)
11        {
12            std::lock_guard<std::mutex> lock(g_topic_manager_mutex);
13            if (!g_topic_manager)
(gdb) n
10        if (!g_topic_manager)
(gdb) n
19        return g_topic_manager;

命令:

# nexti命令可缩写为ni
(gdb) nexti

示例:

(gdb) ni
0x0000000000405265    10      if (!g_topic_manager)
(gdb) ni
0x000000000040526a    10      if (!g_topic_manager)

命令:

# step命令可缩写为s
(gdb) step

示例:

(gdb) c
Continuing.

Thread 1 "main" hit Breakpoint 6, main () at main.cpp:14
14            if (TopicManager::instance()->getNumSubscriptions() > 1000)
(gdb) s
TopicManager::instance () at topic_manager_sim.cpp:9
9    {
(gdb) l
4    L_Subscription getAllSubscription();
5    
6    TopicManagerPtr g_topic_manager;
7    std::mutex g_topic_manager_mutex;
8    const TopicManagerPtr& TopicManager::instance()
9    {
10        if (!g_topic_manager)
11        {
12            std::lock_guard<std::mutex> lock(g_topic_manager_mutex);
13            if (!g_topic_manager)

命令:

# stepi命令可缩写为si
(gdb) stepi

示例:

(gdbsi
TopicManager::instance () at topic_manager_sim.cpp:9

命令:

(gdb) finish

示例:

(gdb) s
TopicManager::instance () at topic_manager_sim.cpp:9
9    {
(gdb) finish 
Run till exit from #0  TopicManager::instance () at topic_manager_sim.cpp:9
0x00000000004010b7 in main () at main.cpp:14
14            if (TopicManager::instance()->getNumSubscriptions() > 1000)
Value returned is $2 = 
  std::shared_ptr<TopicManager> (use count 1, weak count 0) = {get() = 0x620c30}

命令:

continue命令可缩写为c
(gdb) continue

示例:

(gdb) c
Continuing.

Thread 1 "main" hit Breakpoint 6, main () at main.cpp:14
14            if (TopicManager::instance()->getNumSubscriptions() > 1000)

返回上一级


打印/更改变量的值

命令:

# print命令可缩写为p
(gdb) print <variable-name>

示例:

(gdb) p g_shm_manager
$3 = std::shared_ptr<ShmManager> (use count 1, weak count 0) = {get() = 0x620c80}

自动打印变量的值,命令:

(gdb) display <variable-name>

示例:

(gdb) display g_shm_manager
1: g_shm_manager = std::shared_ptr<ShmManager> (use count 1, weak count 0) = {get() = 0x620c80}
(gdb) n
13            std::this_thread::sleep_for(std::chrono::duration<doublestd::milli>(10));
1: g_shm_manager = std::shared_ptr<ShmManager> (use count 1, weak count 0) = {get() = 0x620c80}

取消自动打印变量的值,命令:

(gdb) undisplay <display-number>

查看自动打印的变量有哪些,命令:

(gdb) i display

命令:

(gdb) p <variable-name>=<new-value>

示例:

(gdb) p g_shm_manager._M_ptr
$5 = (ShmManager *) 0x620c80
(gdb) p g_shm_manager._M_ptr=0
$6 = (ShmManager *) 0x0

返回上一级


打印函数参数/局部变量的值

命令:

(gdb) i args

命令:

(gdb) i locals

返回上一级


查看/更改寄存器的值

命令:

(gdb) i registers

示例:

(gdb) i registers 
rax            0x0    0
rbx            0x0    0
rcx            0x7ffff7626c1d    140737343810589
rdx            0x0    0
rsi            0x7fffffffd8e0    140737488345312
rdi            0x0    0
rbp            0x7fffffffd930    0x7fffffffd930
rsp            0x7fffffffd910    0x7fffffffd910
r8             0x0    0
r9             0x7ffff6f42700    140737336583936
r10            0x1381    4993
r11            0x0    0
r12            0x400f50    4198224
r13            0x7fffffffda10    140737488345616
r14            0x0    0
r15            0x0    0
rip            0x4010b2    0x4010b2 <main()+108>
eflags         0x246    [ PF ZF IF ]
cs             0x33    51
ss             0x2b    43
ds             0x0    0
es             0x0    0
fs             0x0    0
gs             0x0    0

命令:

(gdb) i registers all

命令:

(gdb) p $<register-name>

示例:

(gdb) p $rcx
$9 = 140737343810589

命令:

(gdb) p $<register-name>=<new-value>

示例:

(gdb) p $rcx
$9 = 140737343810589
(gdb) p $rcx=1
$10 = 1
(gdb) p $rcx
$11 = 1

返回上一级


查看内存的值

命令:

(gdb) x/<n><f><u> <address>

注:

示例:

# 查看起始地址为0x7fb00008f0后面的4字节的内容,并以十六进制的格式输出
(gdb) x/wx 0x7fb00008f0

返回上一级


调用C/C++函数

命令:

(gdb) call <function-name>

示例:

(gdb) call TopicManager::instance()->subscribe()
$13 = true

返回上一级


调试 coredump 文件

step 1: 查看是否开启 coredump

$ ulimit -c

注:如果输出结果为 0,那么未开启 coredump。

step 2: 开启 coredump

开启 coredump 并且不限制 core 文件大小(仅对当前会话有效):

$ ulimit -c unlimited

step 3: 调试 coredump 文件

$ gdb <executable-file> <coredump-file-path>

注意: <executable-file>为发生 coredump 时所使用的可执行文件。

step 4: 查看堆栈信息

见本文的 查看堆栈信息


如何设置 gdb 日志功能

# 打开日志输出功能,且默认的日志输出文件名称为 gdb.txt
(gdb) set logging on
# 关闭日志输出功能
(gdb) set logging off
# 打开日志输出功能,并指定日志输出文件
# (gdb) set logging on gdb_log.txt
(gdb) set logging on <log-file>

注:打开日志输出功能后,gdb的输出会写入指定的日志文件。

(gdb) set logging file <log-file>
# 设置写日志文件的方式为:覆盖写
(gdb) set logging overwrite on
# 设置写日志文件的方式为:追加写
(gdb) set logging overwrite off

注:gdb 的默认方式为追加写。

注意: 设置覆盖写追加写后,需要再次执行set logging on才会生效。

示例:

file ./main
set logging overwrite on
set logging on test.log
starrt
# gdb的输出只写入日志输出文件,不写入控制台
(gdb) set logging redirect on
# gdb的输出都会写入日志输出文件和控制台
(gdb) set logging redirect off
(gdb) show logging 
Currently logging to "debug_navigator.txt".
Logs will be appended to the log file.
Output is being logged and displayed.

其他命令

(gdb) set pagination off
(gdb) set print elements 0
(gdb) set listsize 30

下一篇:代码调试篇(2):如何编写 gdb 自定义命令

上一篇:代码调试之目录

首页