1.打印好看 set print pretty on
2.常用数据结构打印
3. info locals
4.如何强制转换类型,得加''
错:p *(Test::A*)pObj2
对:p *('Test::A'*)pObj2
5.打印所有堆栈 thread apply all bt
打印堆栈到文件
set logging file /tmp/test.txt
set logging on
thread apply all bt
6.指针强转
p ((std::_Vector_base<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const*, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const*> >*)0x7ffe310cc1a8)[0]._M_impl._M_start[0]
p value_ptr→_meta_vec._M_impl._M_start[7].proto
p _protos._M_impl._M_start[7]
7.string条件断点
b object_pool.h:72 if _limit_name.compare("pre_list") == 0
会报错 Unable to restore previously selected frame:
Selected thread is running.
terminate called after throwing an instance of 'gdb_exception_RETURN_MASK_ERROR'
8.predictor_serve" received signal SIGPIPE, Broken pipe.
When debugging with 'gdb', it is possible to manually disable SIGPIPE as follows:
(gdb) handle SIGPIPE nostop
7.程序卡住了
gdb attach <pid>
,其中<pid>
为您的进程id。进入gdb后输入命令thread apply all bt
查看进程中所有线程的状态,查看进程hang在哪了。
8.
set solib-search-path /opt/compiler/gcc-4.8.2/lib
9.当程序优化了部分变量,可以layout asm 看当前寄存器值。
10.
2. 汇编 + addr2line
对于线上core问题,一般没法再对程序进行去编译优化操作,只能在现有的core文件基础上进行代码定位,这一节我们采用一个例子来介绍如何使用汇编 + addr2line来定位代码行。
从截图可以发现frame 20指示的代码行与实际的代码行是不匹配的,这里我们采用汇编 + addr2line进行修复。
|
这里直接使用了layout asm命令显示了汇编代码,命令使用传送门。最后通过addr2line命令把汇编地址转化成实际代码行。但如果想看汇编代码disassemble func_name (disas namespace::func_name) ,
disas /m fun
将函数代码和汇编命令映射起来, 显示代码每行对应的汇编命令
10. 无规律core栈
无规律core栈问题一般发生于堆内存写坏。函数调用是一个非常精密的过程,任何一个位置发生非预期的读写都会导致程序崩溃。这里可以举个小例子来说明:
1 2 3 4 5 6 |
|
上面的例子core在string析构上,原因是因为string的_M_ptr被改写成了0x11,析构流程变成了非法内存操作。
同理,由于进程堆空间是共享的,一个线程对堆的非法操作就可能会影响另一个线程的正常操作,由于堆分配的随机性,表现出来的现象就是无规律core栈。
针对无规律core栈最好的方式还是借助AddressSanitizer。
|
10.函数栈修复
有时候我们会发现函数调用栈里面会出现很多??的情况,这常发生于栈被写花,某些情况下手动进行修复。函数栈的修复利用的函数栈内存分布知识,见第一节。
----------------------------------- Low addresses ----------------------------------- 0(%rsp) | top of the stack frame | (this is the same as -n(%rbp)) ---------|------------------------- -n(%rbp) | variable sized stack frame -8(%rbp) | varied 0(%rbp) | previous stack frame address 8(%rbp) | return address ----------------------------------- High addresses
从上面的栈示意图可以发现,利用%rbp寄存器即可找到上一个函数的返回地址和栈底指针,再利用addr2line命令找到对应的代码行。这里举一个例子:
1 2 3 4 5 6 |
|