第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直 ...
随机推荐
- Apache httpd的web服务
Apache httpd的web服务 适用于Unix/Linux下的web服务器软件 Apache httpd(开源且免费),虚拟主机,支持HTTPS协议,支持用户认证,支持单个目录的访问控制,支持U ...
- [C++]-map和unordered_map
转自:https://blog.csdn.net/BillCYJ/article/details/78985895 头文件不同 map: #include < map > unordere ...
- Gnucash的投资记录
投资活动主要涉及3个账户:资产(Asset)下的子账户记录投资金额,收入(Income)下的子账户记录投资收入,支出(Expense)下的子账户记录投资费用支出(例如银行手续费,证券交易费等). 以购 ...
- Goland 这些技巧,学会开发效率翻倍!
hi, 大家好,我是 hhf. <Goland 这些实操技巧,你可能还不会!>介绍了日常开发中一些比较好用的技巧.本篇文章继续介绍一些其他比较好用的技巧. 自定义结构 tag Goland ...
- 【原创】利用动态二进制加密实现新型一句话木马之PHP篇
概述 本系列文章重写了java..net.php三个版本的一句话木马,可以解析并执行客户端传递过来的加密二进制流,并实现了相应的客户端工具.从而一劳永逸的绕过WAF或者其他网络防火墙的检测. 本来是想 ...
- SQL 练习40
按照出生日期来计算学生的年龄信息 IF OBJECT_ID('GetStudentAge','FN') IS NOT NULL DROP FUNCTION GetStudentAge GO CREAT ...
- NOIP 模拟 6 模板
题目 题解 这道题是一道启发式合并的题目,每次合并完重构一下线段树就可以,不用线段树合并. 以操作时间为下标,建立一颗线段树,维护小球的个数与小球的颜色数,最后线段树上二分查找. 我们先不用考虑每个节 ...
- 如何在HTML中实现图片的滚动效果
<MARQUEE onmouseover=stop() onmouseout=start() scrollAmount=3 loop=infinite deplay="0"& ...
- 字符串匹配--Regex
利用Regix实现字符串匹配 Eg:匹配嵌入到[]中的字符 string pattern = Regex.Escape("[") + "(.*?)]"; str ...
- WPF 显示3D密集场景,堆场管理系统
又好久好久没写博客了,这次接着上文https://www.cnblogs.com/CSSZBB/p/12785380.html,上文用WPF 的绘图功能,制作了一个伪3D的2.5D控件ThreeDBo ...