第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 实用调试技巧( 上)的更多相关文章
- 第09课:GDB 实用调试技巧(下)
本节课的核心内容: 多线程下禁止线程切换 条件断点 使用 GDB 调试多进程程序 多线程下禁止线程切换 假设现在有 5 个线程,除了主线程,工作线程都是下面这样的一个函数: void thread_p ...
- Chrome 实用调试技巧
Chrome 实用调试技巧 2016-07-23 如今Chrome浏览器无疑是最受前端青睐的工具,原因除了界面简洁.大量的应用插件,良好的代码规范支持.强大的V8解释器之外,还因为Chrome开发者工 ...
- gdb命令调试技巧
gdb命令调试技巧 一.信息显示1.显示gdb版本 (gdb) show version2.显示gdb版权 (gdb) show version or show warranty3.启动时不显示提示信 ...
- Chrome实用调试技巧
如今Chrome浏览器无疑是最受前端青睐的工具,原因除了界面简洁.大量的应用插件,良好的代码规范支持.强大的V8解释器之外,还因为Chrome开发者工具提供了大量的便捷功能,方便我们前端调试代码,我们 ...
- Android Studio 实用调试技巧
Android Studio 是个发工具,其自身带调式环境是很强大的,我们要摆脱只会使用Log打印日志的低效的方法,掌握高级调试技巧对每个Android开发者都是很必要的,废话少说,直入正题 调试方式 ...
- VS2010中的调试技巧
作者: scottgu 这是我的博客中关于VS 2010和.NET 4发布系列的第二十六篇文章. 今天的博文将介绍Visual Studio中的一些实用调试技巧.这是受我朋友Scott Cate (他 ...
- Javascript调试技巧整理
整理一下网上看到的实用调试技巧! 1. 不要使用alert 首先,alert只能打印出字符串,如果打印的对象不是String,则会调用toString()方法将该对象转成字符串(比如转成[object ...
- gdb各种调试命令和技巧
陈皓:用GDB调试程序 GDB概述———— GDB是GNU开源组织发布的一个强大的UNIX下的程序调试工具.或许,各位比较喜欢那种图形界面方式的,像VC.BCB等IDE的调试,但如果你是在UNIX平台 ...
- pwn 题GDB调试技巧和exp模板
GDB分析ELF文件常用的调试技巧 gdb常用命令 首先是gbd+文件名 静态调试 ,gdb attach +文件名 动态调试 为了方便查看堆栈和寄存器 最好是安装peda插件 安装 可以通过pip直 ...
随机推荐
- ABC165C题解
题目 看题目的时候一脸懵,直到看见数据范围 \[N \le 10,\; M \le 10,\; Q \le 50 \] 之后才意识到问题的严重性. 毕竟数据如此的小,我们完全可以用阶乘复杂度算法卡过去 ...
- zookeeper查看启动状态报错:Error contacting service. It is probably not running.
问题描述 我有三台虚拟机master.slave1.slave2.每台虚拟机启动zkServer.sh时都没有报错,然后紧接着查看zkServer.sh的状态,这时候出现了错误:Error conta ...
- Python -类型提示 Type Hints
为什么会有类型提示 Python是一种动态类型语言,这意味着我们在编写代码的时候更为自由,运行时不需要指定变量类型 但是与此同时 IDE 无法像静态类型语言那样分析代码,及时给我们相应的提示,比如字符 ...
- Shellshock 破壳漏洞 Writeup
破壳漏洞 CVE编号:CVE-2014-6271 题目URL:http://www.whalwl.site:8029/ 提示:flag在服务器根目录 ShellShock (CVE-2014-6271 ...
- MySQL自定义函数与存储过程的创建、使用、删除
前言 日常开发中,可能会用到数据库的自定义函数/存储过程,本文记录MySQL对自定义函数与存储过程的创建.使用.删除的使用 通用语法 事实上,可以认为存储过程就是没有返回值的函数,创建/使用/删除都非 ...
- 是的你没看错,HTTP3来了
目录 简介 HTTP成长介绍 不同HTTP协议解决的问题 HTTP3和QUIC TLS1.3 解决HoL阻塞 连接的迁移 总结 简介 很多小伙伴可能还沉浸在HTTP1.1的世界无法自拔,但是时代的洪流 ...
- C#中Finalize方法的问题
ninputer在关于"值类型的Finalize不会被调用"中(http://blog.joycode.com/lijianzhong/archive/2005/01/13/429 ...
- 【springcloud】Eureka 常用配置解析
转自:https://www.cnblogs.com/zyon/p/11023750.html 1. 配置项解析 1.1 通用配置 # 应用名称,将会显示在Eureka界面的应用名称列 spring. ...
- 队列(Queue)\双端队列(Deque)
队列(Queue)\双端队列(Deque) 队列(Queue) 双端队列(Deque) 算法应用 队列(Queue) 特点: 和栈不同,队列的最大特点是先进先出(FIFO),就好像按顺序排队一样.对于 ...
- linux & windows下的动态库制作
动态链接库不是linux独有的特性,在windows下面也存在这样的特性.一般来说,windows下面的动态连接库是以*.dll作为结尾的,而linux下面的动态连接库是以*.so结尾的.和静态链接 ...