gdb 个人总结

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进行修复。

frame 20

layout asm

shell /opt/compiler/gcc-8.2/bin/addr2line -e bin address

这里直接使用了layout asm命令显示了汇编代码,命令使用传送门。最后通过addr2line命令把汇编地址转化成实际代码行。但如果想看汇编代码disassemble func_name (disas namespace::func_name) ,disas /m fun 将函数代码和汇编命令映射起来, 显示代码每行对应的汇编命令

10. 无规律core栈

无规律core栈问题一般发生于堆内存写坏。函数调用是一个非常精密的过程,任何一个位置发生非预期的读写都会导致程序崩溃。这里可以举个小例子来说明:

1

2

3

4

5

6

int main(int argc, char* argv[]) {

    std::string s("abcd");

    *reinterpret_cast<uint64_t*>(&s) = 0x11;

     

    return 0;

}

上面的例子core在string析构上,原因是因为string的_M_ptr被改写成了0x11,析构流程变成了非法内存操作。

同理,由于进程堆空间是共享的,一个线程对堆的非法操作就可能会影响另一个线程的正常操作,由于堆分配的随机性,表现出来的现象就是无规律core栈。

针对无规律core栈最好的方式还是借助AddressSanitizer

#设置编译参数CXXFLAGS

CXXFLAGS="-fPIC -fsanitize=address  -fno-omit-frame-pointer"

#设置链接参数

LDFLAGS="-lasan"

# 设置启动环境变量

export ASAN_OPTIONS=halt_on_error=0:abort_on_error=1:disable_coredump=0

# 启动

LD_PRELOAD=/opt/compiler/gcc-8.2/lib/libasan.so ./bin/xxx

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

#首先找到当前被调用栈上一个栈的栈底指针值和返回地址

/2ag $rbp # 2个单位,a=十六进制,g=8字节单元

#使用上一条命令得到的栈底指针值依次递归

/2ag address

gdb打印数据结构,python编程:​​​​​​你还在用GDB调试程序吗? - 知乎

STLSupport - GDB Wiki

gdb如何回退 又一debug装逼技能:record, replay - 知乎

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值