gdb 常用命令:
*
【gdb [file]】:进入 gdb 调试环境 / 进入 gdb 调试环境,并加载被调试文件 file
*
【file <file>】:加载被调试文件 file
*
【r [运行时参数]】:r=run,运行被调试程序。如果没有设置断点,则运行完整个程序,如果有断点,运行到第一个断点处
*
【start】:开始调试,停在第一行代码处
*
【l [line_number]】:l=list,查看第 1 行附近的源代码 / 查看第 line_number 行附近的源代码
*
【b <line_number>】:b=breakpoint,在第 line_number 行设置断点
*
【b <function>】:让程序在调用函数时触发断点,e.g.【b fun1】。如果希望将断点设置在 C++ 类的成员函数上,可以使用【类名::函数名】的形式设置断点,e.g.【b TestClass::testFunc(int)】
*
【i b】:i b=info break,查看所有的断点信息
*
【d [break_number]】:d=delete,删除所有断点 / 删除编号为 break_number 的断点
*
【bt】:bt=backtrack,查看栈信息
*
【f <x>】:f=frame,切换到第 x 帧。其中 x 会在【bt】命令中显示,从 0 开始,0 表示栈顶。
*
【up/down <x>】:往栈顶/栈底移动 x 帧,当省略 x 时默认为 1
*
【condition】:可以在设置的条件成立时,自动停止当前的程序,先使用【b】或者【watch】设置断点,然后用【condition】来修改这个断点的停止的条件。e.g.【condition <break_number> <expression>】修改当前断点的停止条件为 expression 为真值,【condition <break_number>】 清除断点的停止条件,恢复为一般断点
*
【ignore <break_number> <count>】:忽略该断点的前 count 次停止。e.g.【ignore 1 100】忽略断点1的前100次停止,直到101次程序才停住
*
【s】:s=step,执行一行源程序代码,如果此行代码中有函数调用,则进入该函数
*
【finish】:函数结束,【s】进入到函数后,可用该命令跳出被调函数,返回调用函数
*
【n】:n=next,执行一行源程序代码,不管该行有没有函数调用
*
【c】:c=continue,继续执行被调试程序,直至下一个断点或程序结束
*
【u】:u=until,直到当前循环完成
*
【p <变量名>】:p=print,临时显示某个变量
*
【display <变量名>】:跟踪某个变量,一直显示
*
【undisplay <已被跟踪的某个变量编号的编号>】:取消跟踪某个变量
*
【watch <expression>】:expression 可以是变量、地址、表达式。监视 expression 的值,一旦值有变化,程序停住。取消监视:先用【i b】查看所有断点信息,其中包含监视 expression,然后【d <expression 的编号>】取消监视
*
【set args <argv1> <argv2> ...】:设置运行时参数
*
【show args】:查看运行时参数
*
【q】:q=quit,退出 gdb 调试环境
*
【help <cmd>】:gdb 帮助命令
*
【回车】:重复上次命令
release的coredump,演示
先切换到崩溃的那帧 【 f frame_num】
然后disassemble
0x00007fb1850b679f <+319>: callq 0x7fb18509d670 <_ZNSt18condition_variableC1Ev@plt>
0x00007fb1850b67a4 <+324>: mov 0x1c(%rbx),%eax
0x00007fb1850b67a7 <+327>: cmpq $0x0,0x14195c9(%rip) # 0x7fb1864cfd78
0x00007fb1850b67af <+335>: mov %r15,0xf0(%rsp)
0x00007fb1850b67b7 <+343>: movb $0x0,0x78(%rsp)
0x00007fb1850b67bc <+348>: mov %eax,0x140(%r13)
0x00007fb1850b67c3 <+355>: lea 0x141cc76(%rip),%rax # 0x7fb1864d3440 <_ZL12g_searchMtxN>
0x00007fb1850b67ca <+362>: mov %rax,0x70(%rsp)
0x00007fb1850b67cf <+367>: je 0x7fb1850b67e5 <_ZN12GPUIndexFlat18addSearchParam2MemEP13SVIIDPicParamPmPfPj+389>
0x00007fb1850b67d1 <+369>: lea 0x141cc68(%rip),%rdi # 0x7fb1864d3440 <_ZL12g_searchMtxN>
0x00007fb1850b67d8 <+376>: callq 0x7fb18509d9b0 <pthread_mutex_lock@plt>
0x00007fb1850b67dd <+381>: test %eax,%eax
0x00007fb1850b67df <+383>: jne 0x7fb1850b6bc7 <_ZN12GPUIndexFlat18addSearchParam2MemEP13SVIIDPicParamPmPfPj+1383>
0x00007fb1850b67e5 <+389>: mov 0x130(%r13),%rdi
0x00007fb1850b67ec <+396>: movb $0x1,0x78(%rsp)
0x00007fb1850b67f1 <+401>: lea 0xb0(%rsp),%rsi
=> 0x00007fb1850b67f9 <+409>: mov (%rdi),%rax
0x00007fb1850b67fc <+412>: callq *0x20(%rax)
0x00007fb1850b67ff <+415>: lea 0x70(%rsp),%rax
0x00007fb1850b6804 <+420>: mov 0x8(%rsp),%rdi
0x00007fb1850b6809 <+425>: mov %rax,%rsi
0x00007fb1850b680c <+428>: mov %rax,0x18(%rsp)
0x00007fb1850b6811 <+433>: callq 0x7fb18509e0d0 <_ZNSt18condition_variable4waitERSt11unique_lockISt5mutexE@plt>
0x00007fb1850b6816 <+438>: mov (%rbx),%r13d
0x00007fb1850b6819 <+441>: test %r13,%r13
0x00007fb1850b681c <+444>: je 0x7fb1850b69b3 <_ZN12GPUIndexFlat18addSearchParam2MemEP13SVIIDPicParamPmPfPj+851>
看到汇编不要怂
崩的那个地方 有个这个 =>
0x00007fb1850b67f9和截图的pc是一样的
就是程序计数器,那个东西就是当前程序执行的地址
然后结合代码callq *0x20(%rax),,这个应该是调用pThreadPool->enqueue();
可以确定pThreadPool这个有问题,,原因是我初始化错了,这个其实是个空指针