第08课:GDB 实用调试技巧( 上)
本节课的核心内容:
- 将 print 打印结果显示完整
- 让被 GDB 调试的程序接收信号
- 函数明明存在,添加断点时却无效
将 print 打印结果显示完整
当使用 print 命令打印一个字符串或者字符数组时,如果该字符串太长,print 命令默认显示不全的,我们可以通过在 GDB 中输入 set print element 0 命令设置一下,这样再次使用 print 命令就能完整地显示该变量的所有字符串了。
void ChatSession::OnGetFriendListResponse(const std::shared_ptr<TcpConnection>& conn)
{std::string friendlist;MakeUpFriendListInfo(friendlist, conn);std::ostringstream os;os << "{\"code\": 0, \"msg\": \"ok\", \"userinfo\":" << friendlist << "}";Send(msg_type_getofriendlist, m_seq, os.str());LOG_INFO << "Response to client: userid=" << m_userinfo.userid << ", cmd=msg_type_getofriendlist, data=" << os.str();
}
以上代码中,当第一次打印 friendlist 这个变量值时,只能显示部分字符串。使用 set print element 0 设置以后就能完整地显示出来了。
(gdb) n
563 os << "{\"code\": 0, \"msg\": \"ok\", \"userinfo\":" << friendlist << "}";
(gdb) p friendlist
$1 = "[{\"members\":[{\"address\":\"\",\"birthday\":19900101,\"clienttype\":0,\"customface\":\"\",\"facetype\":2,\"gender\":0,\"mail\":\"\",\"markname\":\"\",\"nickname\":\"bj_man\",\"phonenumber\":\"\",\"signature\":\"\",\"status\":0,\"userid\":4,"...
(gdb) set print element 0
(gdb) p friendlist
$2 = "[{\"members\":[{\"address\":\"\",\"birthday\":19900101,\"clienttype\":0,\"customface\":\"\",\"facetype\":2,\"gender\":0,\"mail\":\"\",\"markname\":\"\",\"nickname\":\"bj_man\",\"phonenumber\":\"\",\"signature\":\"\",\"status\":0,\"userid\":4,\"username\":\"13811411052\"},{\"address\":\"\",\"birthday\":19900101,\"clienttype\":0,\"customface\":\"\",\"facetype\":0,\"gender\":0,\"mail\":\"\",\"markname\":\"\",\"nickname\":\"Half\",\"phonenumber\":\"\",\"signature\":\"\",\"status\":0,\"userid\":5,\"username\":\"15618326596\"},{\"address\":\"\",\"birthday\":19900101,\"clienttype\":0,\"customface\":\"\",\"facetype\":34,\"gender\":0,\"mail\":\"\",\"markname\":\"\",\"nickname\":\"云淡风轻\",\"phonenumber\":\"\",\"signature\":\"\",\"status\":0,\"userid\":7,\"username\":\"china001\"},{\"address\":\"上海市浦东新区南泉路1200号409室\",\"birthday\":20170914,\"clienttype\":0,\"customface\":\"\",\"facetype\":5,\"gender\":0,\"mail\":\"balloonwj@qq.com\",\"markname\":\"\",\"nickname\":\"qqq123\",\"phonenumber\":\"\",\"signature\":\"{“id”:12}\",\"status\":0,\"userid\":10,\"username\":\"qqq\"},{\"address\":\"\",\"birthday\":19900101,\"clienttype\":0,\"customface\":\"be19574dcdd11fb9a96cf00f7e5f0e66\",\"facetype\":0,\"gender\":0,\"mail\":\"\",\"markname\":\"\",\"nickname\":\"TzdnerC\",\"phonenumber\":\"\",\"signature\":\"\",\"status\":0,\"userid\":15,\"username\":\"TzdnerC\"},{\"address\":\"\",\"birthday\":19900101,\"clienttype\":0,\"customface\":\"\",\"facetype\":0,\"gender\":0,\"mail\":\"\",\"markname\":\"\",\"nickname\":\"Barry\",\"phonenumber\":\"\",\"signature\":\"\",\"status\":0,\"userid\":16,\"username\":\"17091203068\"},{\"address\":\"\",\"birthday\":19900101,\"clienttype\":0...太长了,这里省略...
让被 GDB 调试的程序接收信号
请看下面的代码:
void prog_exit(int signo)
{std::cout << "program recv signal [" << signo << "] to exit." << std::endl;
}int main(int argc, char* argv[])
{//设置信号处理signal(SIGCHLD, SIG_DFL);signal(SIGPIPE, SIG_IGN);signal(SIGINT, prog_exit);signal(SIGTERM, prog_exit);int ch;bool bdaemon = false;while ((ch = getopt(argc, argv, "d")) != -1){switch (ch){case 'd':bdaemon = true;break;}}if (bdaemon)daemon_run();//省略无关代码...}
在这个程序中,我们接收到 Ctrl + C 信号(对应信号 SIGINT)时会简单打印一行信息,而当用 GDB 调试这个程序时,由于 Ctrl + C 默认会被 GDB 接收到(让调试器中断下来),导致无法模拟程序接收这一信号。解决这个问题有两种方式:
- 在 GDB 中使用 signal 函数手动给程序发送信号,这里就是 signal SIGINT;
- 改变 GDB 信号处理的设置,通过 handle SIGINT nostop print 告诉 GDB 在接收到 SIGINT 时不要停止,并把该信号传递给调试目标程序 。
(gdb) handle SIGINT nostop print pass
SIGINT is used by the debugger.
Are you sure you want to change it? (y or n) y Signal Stop Print Pass to program Description
SIGINT No Yes Yes Interrupt
(gdb)
函数明明存在,添加断点时却无效
有时候一个函数明明存在,并且我们的程序也存在调试符号,使用 break functionName 添加断点时 GDB 却提示:
Make breakpoint pending on future shared library load? y/n
即使输入 y 命令,添加的断点可能也不会被正确地触发,此时需要改变添加断点的方式,使用该函数所在的代码文件和行号添加断点就能达到效果。
第08课:GDB 实用调试技巧( 上)相关推荐
- C语言第二十课:实用调试技巧
目录 前言: 一.Bug: 二.调试: 1.调试是什么: 2.调试的基本步骤: 3. Debug 与 Release : 三.在Windows环境下进行调试: 1.调试环境的准备: 2.调试的快捷键: ...
- C语言:实用调试技巧
目录 C语言:实用调试技巧 1.什么是bug? 2.调试是什么?有多重要? 3.debug和release的介绍 4.Windows环境调试介绍 5.一些调试的实例 6.如何写出好(易于调试)的代码 ...
- C语言之实用调试技巧
什么是bug? 调试是什么?有多重要? debug和release的介绍. windows环境调试介绍. 一些调试的实例. 如何写出好(易于调试)的代码. 编程常见的错误. 一. 什么是bug? 第一 ...
- VS2017实用调试技巧
目录 历史上的第一个Bug,什么是bug 调试的重要性 现实中的你是会是这样子的吗? 调试的基本步骤 1.发现程序错误的存在 2.以隔离.消除等方式对错误进行定位 3.确定错误产生的原因 4.提出纠正 ...
- 实用调试技巧 Debug Release F10 F11 初始化 越界访问 堆栈 模拟实现库函数
目录 一.什么是bug 二.调试是什么?有多重要? 1.调试 2.调试的基本步骤 三.Debug和Release 四.windows环境调试介绍 1.调试环境的准备 2.学会快捷键 Ctrl+U 改大 ...
- 验08利用gdb工具调试c语言程序,实验4_C开发工具和系统函数
实验四C开发工具和系统函数 (一)C语言开发工具 目的 1.掌握gcc.make.gdb工具 2.熟悉c语言 内容 1.编写一个c语言程序:输出两行文字"Linux下的c也不是太难嘛!&qu ...
- ACM/OI中C++常用优化(实用/调试/技巧)代码(语法)
一.C++万能编译头文件 #include<bits/stdc++.h> 从 #include <iostream> #include <cstdio> #incl ...
- C语言初阶——实用调试技巧
- 【C语言】实用调试技巧与const函数提升代码健壮性
作者简介:大家好我是狂暴于涛侠
- 实用调试的技巧,VS编译器常用调试详解
实用调试技巧 文章目录 实用调试技巧 什么是bug? 调试是什么?有多重要? Debug和Release的介绍 windows环境调试介绍 一些调试的实例 如何写出好的代码 const 什么是bug? ...
最新文章
- linux 系统调用 open函数使用
- XLNet团队:赢BERT靠的并不是数据集更大,公平对决也碾压对手
- centos7安装ftp_python 编译安装
- 【转】数据库的乐观锁和悲观锁
- 学习笔记(30):Python网络编程并发编程-Event事件
- Postgre体系结构图
- 当卷烟厂也那么卷后……
- [LeetCode][easy]Create Target Array
- hdu 5735 Born Slippy 暴力
- vue 开发app处理手机返回键问题
- 阿里云服务器大陆机房和香港机房如何选择?
- 新侨移民告诉你:为什么要移民新西兰?
- Verilog数码显示器00~99循环计数器电路
- 在自己的数据集上训练CrowdDet过程记录
- 什么是高度塌陷 以及高度塌陷的解决办法
- 杂项-公司:奇虎360
- python 数据挖掘 之 对数据进行简单预处理(1)
- android模拟器计算器,兔子计算器模拟器Wabbitem
- 用OpenZeppelin在RSK上进行以太坊ERC20代币开发
- C语言用pthread.h创建线程
热门文章
- 好玩的抖音、快手无水印视频下载工具
- 自动驾驶仿真:Carsim、NI和VTD联合仿真课题一
- 【信号与系统|吴大正】4:信号分解、傅里叶变换与信号谱(上)
- deepin 应用市场安装软件失败_深度商店软件无法安装问题解决方案
- 苹果cms V10模板 仿挖片自适应电影模板
- 用程序找出计算机c盘内容,电脑C盘空间空间清理方法
- 易语言_酷Q机器人插件_01
- hmcl手机版_hmcl启动器app下载
- hmcl手机版_hmcl启动器手机版下载-hmcl启动器官方正版下载v3.3.172-1y2y游戏
- 2022年四方系统/四方支付系统部署实战,以及细节讨论,Gitee版本