GDB调试实战一基础准备

222 篇文章 92 订阅

一、GDB应用

在前面讲过了很多GDB的命令和相关的调试小程序,但是好多人发现在学习完成这些命令后,不知道如何应用到实际的工程中去,这里就使用一个实际的工程进行一下调试。为了合乎规范,使用的并不是完整和全面的公司的代码,而在上面进行了缩减了的代码,但整体的架构几乎一致,完全可以和实际工程比拟。

二、基本情况介绍

1、服务器软硬件
服务器使用的是2*64=128核心的DELL服务器,内存128G,SSH远端登陆。CentOS7的操作系统。

2、编译工具

使用cmake3.3 ,gcc-g++ 4.8.5

3、调试工具

使用gdb-7.6调试。

4、代码结构

三、启动调试前的准备

这个程序是一个网络服务端的高并发的简化,为了简单并没有把epoll弄进来,而是通过两个线程模拟发送和接收,并送到逻辑处理队列进行整包控制来进行。
先看一下崩溃转储的设置:

[root@server1 build]# ulimit -c
10240

如果为0的话,请使用:
ulimit -c N 设置大小,N单位为k。
上面的设置只适合当前终端,退出后变为0
永久修改:

/etc/profile:全局
.bash_profile:当前用户
ulimit  -c  N
source .bash_profile

设置这个参数的目的是为了在调试时如果进程崩溃,可以产生转储文件Core。

写一个简单的CMakeLists.txt,然后放到当前的根目录下,创建一个文件夹build,然后进入到这个文件夹:

 cd build
 cmake ..
 make 

就会在此目录下生成可执行文件,以后所有的操作都是以这个文件夹为基本目录操作的,请知悉。

四、启动进程

然后启动进程:

[root@server1 build]# ls
CMakeCache.txt  CMakeFiles  cmake_install.cmake  core.70236  gdbTest  Makefile
[root@server1 build]# nohup ./gdbTest >1.log 2>&1 &
[1]4144

这个4144是启动的进程ID,和ps -ef|grep gdbTest得到的ID一样。如果不是使用上面的方法启动进程,可以使用这个命令来得到当前的进程ID,效果一样。然后使用tail命令来查看程序的正常输出。

[root@server1 build]# ls
1.log  CMakeCache.txt  CMakeFiles  cmake_install.cmake  core.70236  gdbTest  Makefile
[root@server1 build]# tail -f -n 20 1.log 
dataparse tmp netData:100
dataparse tmp netData:100
dataparse tmp netData:100
dataparse tmp netData:100
dataparse tmp comData:60
dataparse tmp comData:60

这里将使用动态加载已运行的进程的方式来调试:

[root@server1 build]# ls
1.log  CMakeCache.txt  CMakeFiles  cmake_install.cmake  core.70236  gdbTest  Makefile
[root@server1 build]# gdb attach 4144  (注意:调试完成要detach)
GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-120.el7
Copyright (C) 2013 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-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
attach: No such file or directory.
Attaching to process 4144
Reading symbols from /root/projects/gdbTest/build/gdbTest...done.
Reading symbols from /lib64/libstdc++.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib64/libstdc++.so.6
Reading symbols from /lib64/libm.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib64/libm.so.6
Reading symbols from /lib64/libgcc_s.so.1...(no debugging symbols found)...done.
Loaded symbols for /lib64/libgcc_s.so.1
Reading symbols from /lib64/libpthread.so.0...(no debugging symbols found)...done.
[New LWP 4146]
[New LWP 4145]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
Loaded symbols for /lib64/libpthread.so.0
Reading symbols from /lib64/libc.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib64/libc.so.6
Reading symbols from /lib64/ld-linux-x86-64.so.2...(no debugging symbols found)...done.
Loaded symbols for /lib64/ld-linux-x86-64.so.2
0x00007f18884b0017 in pthread_join () from /lib64/libpthread.so.0
Missing separate debuginfos, use: debuginfo-install glibc-2.17-317.el7.x86_64 libgcc-4.8.5-44.el7.x86_64 libstdc++-4.8.5-44.el7.x86_64
(gdb) stop
(gdb) 

此处需要root权限,如果没有则会报权限受限,sudo或者其它可以取得root方式均可。启动后使用stop命令停止当前进程 。

执行一下list命令,查看当前可以看到的代码,发现并没导入的代码

(gdb) l
1       #include <cstdio>
2       #include "ModuleNet.h"
3
4       int main()
5       {
6               ModuleNet mn;
7               std::string ip = "192.168.0.2";
8               mn.Init(0, ip);
9               mn.Start(0);
10              getchar();
(gdb)

如果想查看当前路径,需要加上shell表示是执行的shell命令:

(gdb) shell ls
1.log  CMakeCache.txt  CMakeFiles  cmake_install.cmake  core.70236  gdbTest  Makefile
(gdb) 

如果想调试哪个路径下的文件,可以使用下面的命令:

(gdb) dir ../inet/
Source directories searched: /root/projects/gdbTest/build/../inet:$cdir:$cwd
(gdb) 

导入想要调试的文件路径。

(gdb) l Server.cpp:18
13              Server::~Server()
14              {
15                      this->id.join();
16                      this->idwork.join();
17              }
18              int Server::InitServer(int count, std::string & ip)
19              {
20                      if (nullptr == this->pData_)
21                      {
22                              this->pData_ = std::make_shared<data::IData>();
(gdb) 

如果没有前面的 dir命令,则无法进行查看。

(gdb) show dir
Source directories searched: /root/projects/gdbTest/build/../inet:$cdir:$cwd
(gdb) 

使用:号可以连接导入多个路径

(gdb) dir ../inet/:../data/netdata/:../data/comdata/
Source directories searched: 
/root/projects/gdbTest/build/../inet:/root/projects/gdbTest/build/../data/netdata:/root/projects/gdbTest/build/../data/comdata:$cdir:$cwd
(gdb) 

这样就可以在关心的文件中进行各种操作如下断点。假使不希望再使用当前的导入路径的文件可以直接使用dir命令,则当前所有的导入都会清除,只留下默认部分。

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

准备好上述的基本的环境后,可以下断点了。断点设置方法在前面的GDB应用中介绍过,下面使用其中的方法来进行断点操作。
如果想在函数中下断点,但又不太清楚的记得函数名称可以用名空间名称-类名等依次向下点击两次TAB键,则会自动出现相关的符号:

(gdb) b inet::Server
Server
Server::InitServer(int, std::string&)
Server::RunWork()
Server::RunWork()::{lambda()#1}&& std::forward<inet::Server::RunWork()::{lambda()#1}>(std::remove_reference<inet::Server::RunWork()::{lambda()#1}>::type&)
Server::RunWork()::{lambda()#1}::operator()() const
Server::Server()
Server::Start()
Server::Start()::{lambda()#1}&& std::forward<inet::Server::Start()::{lambda()#1}>(std::remove_reference<inet::Server::Start()::{lambda()#1}>::type&)
Server::Start()::{lambda()#1}::operator()() const
Server::Stop()
Server::~Server()

如果进一步指定一个函数的开头字母:

(gdb) b inet::Server::S
Server()
Start()
Start()::{lambda()#1}&& std::forward<inet::Server::Start()::{lambda()#1}>(std::remove_reference<inet::Server::Start()::{lambda()#1}>::type&)
Start()::{lambda()#1}::operator()() const
Stop()

当然,还是习惯于用行号来下断点:

(gdb) l Server.cpp:33
28              }
29              int Server::Start()
30              {
31                      int num = 0;
32                      this->id = std::thread([&]() {
33                              //    
34                              while (!quit_)
35                              {
36                                      int len = strlen(barr[num % 10]);
37                                      memmove(dbuf_, barr[num%10], len);
(gdb) b Server.cpp:36
Breakpoint 1 at 0x417e3e: file /root/projects/gdbTest/inet/Server.cpp, line 36.
(gdb) 

可以对断点进行查看和删除:

(gdb) info b
Num     Type           Disp Enb Address            What
2       breakpoint     keep y   0x0000000000417e3e in inet::Server::__lambda0::operator()() const at /root/projects/gdbTest/inet/Server.cpp:36
(gdb) delete 2
(gdb) info b
No breakpoints or watchpoints.
(gdb) b Server.cpp:36
Breakpoint 3 at 0x417e3e: file /root/projects/gdbTest/inet/Server.cpp, line 36.
(gdb) delete
Delete all breakpoints? (y or n) y
(gdb) 

还可以对断点进行禁用、启用和忽略:

(gdb) b inet::Server::Start
Breakpoint 4 at 0x417f64: file /root/projects/gdbTest/inet/Server.cpp, line 31.
(gdb) clear
No source file specified.
(gdb) info b
Num     Type           Disp Enb Address            What
4       breakpoint     keep y   0x0000000000417f64 in inet::Server::Start() at /root/projects/gdbTest/inet/Server.cpp:31
(gdb) disable 4
(gdb) info b
Num     Type           Disp Enb Address            What
4       breakpoint     keep n   0x0000000000417f64 in inet::Server::Start() at /root/projects/gdbTest/inet/Server.cpp:31
(gdb) enable 
(gdb) info b
Num     Type           Disp Enb Address            What
4       breakpoint     keep y   0x0000000000417f64 in inet::Server::Start() at /root/projects/gdbTest/inet/Server.cpp:31
(gdb) in
inferior           info               init-if-undefined  interpreter-exec   interrupt          
(gdb) ignore 4
Second argument (specified ignore-count) is missing.
(gdb) info b
Num     Type           Disp Enb Address            What
4       breakpoint     keep y   0x0000000000417f64 in inet::Server::Start() at /root/projects/gdbTest/inet/Server.cpp:31
(gdb) 

同样,使用clear也可以删除断点,clear Server.cpp:31 就会把上面的断点4给删除。需要注意的是,clear这个命令是基于行命令删除的(也就是说基于行号)。

查看一下当前的线程:

(gdb) info thread
  Id   Target Id         Frame 
  3    Thread 0x7f18880d8700 (LWP 4145) "gdbTest" 0x00007f188819e85d in nanosleep () from /lib64/libc.so.6
  2    Thread 0x7f18878d7700 (LWP 4146) "gdbTest" 0x00007f188819e85d in nanosleep () from /lib64/libc.so.6
* 1    Thread 0x7f18890fa740 (LWP 4144) "gdbTest" 0x00007f18884b0017 in pthread_join () from /lib64/libpthread.so.0

查看当前所有线程的堆栈信息:

(gdb) thread apply all bt

Thread 3 (Thread 0x7f18880d8700 (LWP 4145)):
#0  0x00007f188819e85d in nanosleep () from /lib64/libc.so.6
#1  0x00007f188819e6f4 in sleep () from /lib64/libc.so.6
#2  0x0000000000417f3b in inet::Server::__lambda0::operator() (__closure=0xc913c0) at /root/projects/gdbTest/inet/Server.cpp:42
#3  0x0000000000419e96 in std::_Bind_simple<inet::Server::Start()::__lambda0()>::_M_invoke<>(std::_Index_tuple<>) (this=0xc913c0) at /usr/include/c++/4.8.2/functional:1732
#4  0x0000000000419d45 in std::_Bind_simple<inet::Server::Start()::__lambda0()>::operator()(void) (this=0xc913c0) at /usr/include/c++/4.8.2/functional:1720
#5  0x0000000000419c76 in std::thread::_Impl<std::_Bind_simple<inet::Server::Start()::__lambda0()> >::_M_run(void) (this=0xc913a8) at /usr/include/c++/4.8.2/thread:115
#6  0x00007f1888c90330 in ?? () from /lib64/libstdc++.so.6
#7  0x00007f18884aeea5 in start_thread () from /lib64/libpthread.so.0
#8  0x00007f18881d796d in clone () from /lib64/libc.so.6

Thread 2 (Thread 0x7f18878d7700 (LWP 4146)):
#0  0x00007f188819e85d in nanosleep () from /lib64/libc.so.6
#1  0x00007f188819e6f4 in sleep () from /lib64/libc.so.6
#2  0x0000000000418122 in inet::Server::__lambda1::operator() (__closure=0xc91660) at /root/projects/gdbTest/inet/Server.cpp:77
#3  0x0000000000419e38 in std::_Bind_simple<inet::Server::RunWork()::__lambda1()>::_M_invoke<>(std::_Index_tuple<>) (this=0xc91660) at /usr/include/c++/4.8.2/functional:1732
#4  0x0000000000419d27 in std::_Bind_simple<inet::Server::RunWork()::__lambda1()>::operator()(void) (this=0xc91660) at /usr/include/c++/4.8.2/functional:1720
#5  0x0000000000419c58 in std::thread::_Impl<std::_Bind_simple<inet::Server::RunWork()::__lambda1()> >::_M_run(void) (this=0xc91648) at /usr/include/c++/4.8.2/thread:115
#6  0x00007f1888c90330 in ?? () from /lib64/libstdc++.so.6
#7  0x00007f18884aeea5 in start_thread () from /lib64/libpthread.so.0
#8  0x00007f18881d796d in clone () from /lib64/libc.so.6

Thread 1 (Thread 0x7f18890fa740 (LWP 4144)):
#0  0x00007f18884b0017 in pthread_join () from /lib64/libpthread.so.0
#1  0x00007f1888c900f7 in std::thread::join() () from /lib64/libstdc++.so.6
#2  0x0000000000417d36 in inet::Server::~Server (this=0xc8f058, __in_chrg=<optimized out>) at /root/projects/gdbTest/inet/Server.cpp:15
#3  0x000000000041c9a4 in __gnu_cxx::new_allocator<inet::Server>::destroy<inet::Server> (this=0xc8f050, __p=0xc8f058) at /usr/include/c++/4.8.2/ext/new_allocator.h:124
#4  0x000000000041c961 in std::allocator_traits<std::allocator<inet::Server> >::_S_destroy<inet::Server> (__a=..., __p=0xc8f058) at /usr/include/c++/4.8.2/bits/alloc_traits.h:281
#5  0x000000000041c917 in std::allocator_traits<std::allocator<inet::Server> >::destroy<inet::Server> (__a=..., __p=0xc8f058) at /usr/include/c++/4.8.2/bits/alloc_traits.h:405
#6  0x000000000041c85f in std::_Sp_counted_ptr_inplace<inet::Server, std::allocator<inet::Server>, (__gnu_cxx::_Lock_policy)2>::_M_dispose (this=0xc8f040)
    at /usr/include/c++/4.8.2/bits/shared_ptr_base.h:407
#7  0x0000000000415aea in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release (this=0xc8f040) at /usr/include/c++/4.8.2/bits/shared_ptr_base.h:144
#8  0x0000000000415639 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count (this=0x7ffc47678008, __in_chrg=<optimized out>) at /usr/include/c++/4.8.2/bits/shared_ptr_base.h:546
#9  0x000000000041bf24 in std::__shared_ptr<inet::Server, (__gnu_cxx::_Lock_policy)2>::~__shared_ptr (this=0xaf7e47678000, __in_chrg=<optimized out>) at /usr/include/c++/4.8.2/bits/shared_ptr_base.h:781
#10 0x000000000041bf62 in std::shared_ptr<inet::Server>::~shared_ptr (this=0x7ffc47678000, __in_chrg=<optimized out>) at /usr/include/c++/4.8.2/bits/shared_ptr.h:93
#11 0x000000000041be28 in ModuleNet::~ModuleNet (this=0x7ffc47678000, __in_chrg=<optimized out>) at /root/projects/gdbTest/ModuleNet.cpp:8
#12 0x000000000041bd11 in main () at /root/projects/gdbTest/main.cpp:12

进一步查看一下当前线程调试调度锁的情况,并通过设置参数进行锁定和放开:

(gdb) show scheduler-locking 
Mode for locking scheduler during execution is "step".
(gdb) set scheduler-locking on
(gdb) show scheduler-locking 
Mode for locking scheduler during execution is "on".
(gdb) set scheduler-locking off
(gdb) show scheduler-locking 
Mode for locking scheduler during execution is "off".

通过这个命令,可以强制指定只调试某个线程,当初第一次用这个命令时,还忽视了,结果发现另外一个线程死活也进不了断点。初学者不要忘记不用了改回到初始状态。
查看一下当前线程的帧和相关堆栈:

(gdb) info frame
Stack level 0, frame at 0x7ffc47677ea0:
 rip = 0x7f18884b0017 in pthread_join; saved rip 0x7f1888c900f7
 called by frame at 0x7ffc47677eb0
 Arglist at 0x7ffc47677e38, args: 
 Locals at 0x7ffc47677e38, Previous frame's sp is 0x7ffc47677ea0
 Saved registers:
  rbx at 0x7ffc47677e68, rbp at 0x7ffc47677e70, r12 at 0x7ffc47677e78, r13 at 0x7ffc47677e80, r14 at 0x7ffc47677e88, r15 at 0x7ffc47677e90, rip at 0x7ffc47677e98
(gdb) bt
#0  0x00007f18884b0017 in pthread_join () from /lib64/libpthread.so.0
#1  0x00007f1888c900f7 in std::thread::join() () from /lib64/libstdc++.so.6
#2  0x0000000000417d36 in inet::Server::~Server (this=0xc8f058, __in_chrg=<optimized out>) at /root/projects/gdbTest/inet/Server.cpp:15
#3  0x000000000041c9a4 in __gnu_cxx::new_allocator<inet::Server>::destroy<inet::Server> (this=0xc8f050, __p=0xc8f058) at /usr/include/c++/4.8.2/ext/new_allocator.h:124
#4  0x000000000041c961 in std::allocator_traits<std::allocator<inet::Server> >::_S_destroy<inet::Server> (__a=..., __p=0xc8f058) at /usr/include/c++/4.8.2/bits/alloc_traits.h:281
#5  0x000000000041c917 in std::allocator_traits<std::allocator<inet::Server> >::destroy<inet::Server> (__a=..., __p=0xc8f058) at /usr/include/c++/4.8.2/bits/alloc_traits.h:405
#6  0x000000000041c85f in std::_Sp_counted_ptr_inplace<inet::Server, std::allocator<inet::Server>, (__gnu_cxx::_Lock_policy)2>::_M_dispose (this=0xc8f040)
    at /usr/include/c++/4.8.2/bits/shared_ptr_base.h:407
#7  0x0000000000415aea in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release (this=0xc8f040) at /usr/include/c++/4.8.2/bits/shared_ptr_base.h:144
#8  0x0000000000415639 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count (this=0x7ffc47678008, __in_chrg=<optimized out>) at /usr/include/c++/4.8.2/bits/shared_ptr_base.h:546
#9  0x000000000041bf24 in std::__shared_ptr<inet::Server, (__gnu_cxx::_Lock_policy)2>::~__shared_ptr (this=0xaf7e47678000, __in_chrg=<optimized out>) at /usr/include/c++/4.8.2/bits/shared_ptr_base.h:781
#10 0x000000000041bf62 in std::shared_ptr<inet::Server>::~shared_ptr (this=0x7ffc47678000, __in_chrg=<optimized out>) at /usr/include/c++/4.8.2/bits/shared_ptr.h:93
#11 0x000000000041be28 in ModuleNet::~ModuleNet (this=0x7ffc47678000, __in_chrg=<optimized out>) at /root/projects/gdbTest/ModuleNet.cpp:8
#12 0x000000000041bd11 in main () at /root/projects/gdbTest/main.cpp:12
(gdb) 

如果想进入某个线程并查看相关堆栈和具体的信息:

(gdb) thread 3
[Switching to thread 3 (Thread 0x7f18880d8700 (LWP 4145))]
#0  0x00007f188819e85d in nanosleep () from /lib64/libc.so.6
(gdb) bt
#0  0x00007f188819e85d in nanosleep () from /lib64/libc.so.6
#1  0x00007f188819e6f4 in sleep () from /lib64/libc.so.6
#2  0x0000000000417f3b in inet::Server::__lambda0::operator() (__closure=0xc913c0) at /root/projects/gdbTest/inet/Server.cpp:42
#3  0x0000000000419e96 in std::_Bind_simple<inet::Server::Start()::__lambda0()>::_M_invoke<>(std::_Index_tuple<>) (this=0xc913c0) at /usr/include/c++/4.8.2/functional:1732
#4  0x0000000000419d45 in std::_Bind_simple<inet::Server::Start()::__lambda0()>::operator()(void) (this=0xc913c0) at /usr/include/c++/4.8.2/functional:1720
#5  0x0000000000419c76 in std::thread::_Impl<std::_Bind_simple<inet::Server::Start()::__lambda0()> >::_M_run(void) (this=0xc913a8) at /usr/include/c++/4.8.2/thread:115
#6  0x00007f1888c90330 in ?? () from /lib64/libstdc++.so.6
#7  0x00007f18884aeea5 in start_thread () from /lib64/libpthread.so.0
#8  0x00007f18881d796d in clone () from /lib64/libc.so.6
(gdb) bt
#0  0x00007f188819e85d in nanosleep () from /lib64/libc.so.6
#1  0x00007f188819e6f4 in sleep () from /lib64/libc.so.6
#2  0x0000000000417f3b in inet::Server::__lambda0::operator() (__closure=0xc913c0) at /root/projects/gdbTest/inet/Server.cpp:42
#3  0x0000000000419e96 in std::_Bind_simple<inet::Server::Start()::__lambda0()>::_M_invoke<>(std::_Index_tuple<>) (this=0xc913c0) at /usr/include/c++/4.8.2/functional:1732
#4  0x0000000000419d45 in std::_Bind_simple<inet::Server::Start()::__lambda0()>::operator()(void) (this=0xc913c0) at /usr/include/c++/4.8.2/functional:1720
#5  0x0000000000419c76 in std::thread::_Impl<std::_Bind_simple<inet::Server::Start()::__lambda0()> >::_M_run(void) (this=0xc913a8) at /usr/include/c++/4.8.2/thread:115
#6  0x00007f1888c90330 in ?? () from /lib64/libstdc++.so.6
#7  0x00007f18884aeea5 in start_thread () from /lib64/libpthread.so.0
#8  0x00007f18881d796d in clone () from /lib64/libc.so.6
(gdb) info frame
Stack level 0, frame at 0x7f18880d7c70:
 rip = 0x7f188819e85d in nanosleep; saved rip 0x7f188819e6f4
 called by frame at 0x7f18880d7e50
 Arglist at 0x7f18880d7c58, args: 
 Locals at 0x7f18880d7c58, Previous frame's sp is 0x7f18880d7c70
 Saved registers:
  rip at 0x7f18880d7c68
(gdb) bt
#0  0x00007f188819e85d in nanosleep () from /lib64/libc.so.6
#1  0x00007f188819e6f4 in sleep () from /lib64/libc.so.6
#2  0x0000000000417f3b in inet::Server::__lambda0::operator() (__closure=0xc913c0) at /root/projects/gdbTest/inet/Server.cpp:42
#3  0x0000000000419e96 in std::_Bind_simple<inet::Server::Start()::__lambda0()>::_M_invoke<>(std::_Index_tuple<>) (this=0xc913c0) at /usr/include/c++/4.8.2/functional:1732
#4  0x0000000000419d45 in std::_Bind_simple<inet::Server::Start()::__lambda0()>::operator()(void) (this=0xc913c0) at /usr/include/c++/4.8.2/functional:1720
#5  0x0000000000419c76 in std::thread::_Impl<std::_Bind_simple<inet::Server::Start()::__lambda0()> >::_M_run(void) (this=0xc913a8) at /usr/include/c++/4.8.2/thread:115
#6  0x00007f1888c90330 in ?? () from /lib64/libstdc++.so.6
#7  0x00007f18884aeea5 in start_thread () from /lib64/libpthread.so.0
#8  0x00007f18881d796d in clone () from /lib64/libc.so.6

栈帧可以自由的在范围内上下选择:

(gdb) up 1
#1  0x00007f188819e6f4 in sleep () from /lib64/libc.so.6
(gdb) up 2
#3  0x0000000000419e96 in std::_Bind_simple<inet::Server::Start()::__lambda0()>::_M_invoke<>(std::_Index_tuple<>) (this=0xc913c0) at /usr/include/c++/4.8.2/functional:1732
1732                  std::forward<_Args>(std::get<_Indices+1>(_M_bound))...);
(gdb) down 1
#2  0x0000000000417f3b in inet::Server::__lambda0::operator() (__closure=0xc913c0) at /root/projects/gdbTest/inet/Server.cpp:42
42                                      sleep(1);
(gdb) 

怎么样?这些基础命令的使用在实际的工程中发现它的更具体的用法了吧。

最后,输入detach命令,让程序恢复正常运行。

如果想退出调试,quit即可。

五、总结

GDB的使用非常灵活和强大,需要把相关文档中的知识和实际的应用不断的结合,才能形成自己的一套调试技巧和调试思想。工具谁都会用,但是怎么才能用好,更能为我所用,这才是根本。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值