目录

c++调试

堆栈介绍

寄存器

i386

register

x86_64

/images/cpp/register.png

汇编执行流程

#include <stdio.h>

int sum(int x, int y) {
  int accum = 1;
  accum = accum + x + y;
  return accum;
}

int main(int argc, char **argv) {
  int x = 1, y = 2;
  int result = sum(x, y);
  printf("result = %d", result);
  return 0;
}

若编译时带有调试信息,查看汇编使用LLDB或GDB就可以,但当可执行文件没有调试信息时,可使用objdump -S a.out来查看

main 对应的汇编:

test`main:
    0x401160 <+0>:  pushq  %rbp   // 将上级函数的栈基地址压入main的栈底。push会自动增加rsp的值,即rsp始终指向栈顶
    0x401161 <+1>:  movq   %rsp, %rbp // rbp指向main的栈底
    0x401164 <+4>:  subq   $0x20, %rsp  //rsp下移32字节,为main函数执行保留一定的栈空间
    0x401168 <+8>:  movl   $0x0, -0x4(%rbp)
    0x40116f <+15>: movl   %edi, -0x8(%rbp)
    0x401172 <+18>: movq   %rsi, -0x10(%rbp)
    0x401176 <+22>: movl   $0x1, -0x14(%rbp)
    0x40117d <+29>: movl   $0x2, -0x18(%rbp)
    0x401184 <+36>: movl   -0x14(%rbp), %edi
    0x401187 <+39>: movl   -0x18(%rbp), %esi
    0x40118a <+42>: callq  0x401130                  ; sum at main.cpp:3
    0x40118f <+47>: movl   %eax, -0x1c(%rbp)
    0x401192 <+50>: movl   -0x1c(%rbp), %esi
    0x401195 <+53>: movabsq $0x402004, %rdi           ; imm = 0x402004 
    0x40119f <+63>: movb   $0x0, %al
    0x4011a1 <+65>: callq  0x401030                  ; symbol stub for: printf
    0x4011a6 <+70>: xorl   %ecx, %ecx
    0x4011a8 <+72>: movl   %eax, -0x20(%rbp)
    0x4011ab <+75>: movl   %ecx, %eax
    0x4011ad <+77>: addq   $0x20, %rsp
    0x4011b1 <+81>: popq   %rbp
    0x4011b2 <+82>: retq   

sum 对应的汇编:

test`sum:
    0x401130 <+0>:  pushq  %rbp
    0x401131 <+1>:  movq   %rsp, %rbp
    0x401134 <+4>:  movl   %edi, -0x4(%rbp)
    0x401137 <+7>:  movl   %esi, -0x8(%rbp)
    0x40113a <+10>: movl   $0x1, -0xc(%rbp)
    0x401141 <+17>: movl   -0xc(%rbp), %eax
    0x401144 <+20>: addl   -0x4(%rbp), %eax
    0x401147 <+23>: addl   -0x8(%rbp), %eax
    0x40114a <+26>: movl   %eax, -0xc(%rbp)
    0x40114d <+29>: movl   -0xc(%rbp), %eax
    0x401150 <+32>: popq   %rbp
    0x401151 <+33>: retq   

执行流程:

/images/cpp/asm.jpg

gdb

打印堆栈

打印当前线程堆栈:bt

打印所有线程堆栈:thread apply all bt

coredump

查看是否开启

ulimit -a

开启: ulimit -c unlimited

这个设置只对当前登录回话有效。如果想要这个设置持久有效,可以把它写入到/etc/security/limits.conf文件中

sudo vi /etc/security/limits.conf
* soft core unlimited
* soft hard unlimited

设置coredump文件保存路径

sudo vi /etc/sysctl.conf
kernel.core_pattern=/var/crash/%E.%p.%t.%s
sudo sysctl -p

其中 %E:程序文件的完整路径(路径中的/会被!替代);%p:进程 ID;%t:进程奔溃的时间戳;%s:哪个信号让进程奔溃