vlambda博客
学习文章列表

Linux C/C++代码 使用gdb进行coredump调试


  • Coredump文件是什么?
    1.1 产生根因
    1.2 如何打开?
    1.3 如何设置文件名以及路径

  • GDB理论部分
    2.1 基本命令
    2.2 被忽略但实用的命令
    2.3 实用的GDB设置

  • GDB操作部分
    3.1 coredump文件是否任何时候都产生?
    3.2 系统函数是否可以打印coredump信息?
    3.3 调试案列(基本使用)
    3.4 调试案列(多进程)
    3.5 调试案列(多线程以及线程锁问题)
    3.6 调试案列(容器调试)
    3.7 调试类接口(重载函数以及虚函数)
    3.8 调试案列(反汇编查看DUMP信息)

Coredump文件是什么?

当程序运行的过程中异常终止或崩溃,操作系统会将程序当时的内存状态记录下来,保存在文件中,这种行为就叫做核心转储。Coredump文件包括寄存器信息(包括程序指针、栈指针等)、内存管理信息等。
产生根因:
如果信号均是采用默认操作,以下列的几种信号,它们在发生时会产生 core dump,如下图:
  1. 内存访问越界 (数组越界、字符串无\0结束符、字符串读写越界)

  2. 多线程程序中使用了线程不安全的函数,如不可重入函数(函数体内使用了静态的数据结构,函数体内调用 标准I/O函数,函数体内调用了malloc()或者free()函数)

  3. 多线程读写的数据未加锁保护(临界区资源需要互斥访问)

进程退出都会产生coredump?

       使用 Ctrl+z 来挂起一个进程或者 Ctrl+C 结束一个进程均不会产生 core dump,因为会向进程发SIGTSTP 信号,该信号的默认操作为暂停进程(Stop Process;后者会向进程发出SIGINT 信号,该信号默认操作为终止进程(Terminate Process), kill -9 命令会发出 SIGKILL 命令,该命令默认为终止进程。而如果我们使用 Ctrl+\ 来终止一个进程,会向进程发出 SIGQUIT 信号,默认是会产生 core dump 的。


Coredump 如何打开

在终端中输入命令 ulimit -c ,输出的结果为 0,说明默认是关闭 core dump 的,即当程序发生崩溃,也不会生成 core dump 文件。打开两种办法:
1.Shell 命令行执行 ulimit -c unlimited 来开启 core dump 功能,只是本此生效,本用户生效,并且不限制 core dump 文件的大小;如果需要限制文件的大小,将 unlimited 改成你想生成 core 文件最大的大小,注意单位为 blocks(KB)
2.vi /etc/profile 修改如下图蓝色所示,之后使用 . /etc/profile 或source /etc/profile 让其配置生效。

如何设置文件名以及路径

默认生成的 core 文件保存在可执行文件所在的目录下,文件名就为core。通过修改/proc/sys/kernel/core_uses_pid 文件可以让生成 core 文件名是否自动加上 pid 号。
  • 1

例如 echo 1 > /proc/sys/kernel/core_uses_pid ,生成的 core 文件名将会变成 core.pid,其中 pid 表示该进程的 PID。
还可以修改 /proc/sys/kernel/core_pattern 来控制生成 core 文件保存的位置以及文件名格式。
例如: echo “/var/coredump/coredump_for_%p_%t_%e” > /proc/sys/kernel/core_pattern
设置生成的 core 文件保存在 “/var/coredump/” 目录下,文件名格式为 “coredump_for_pid-时间戳-命令名”,如下图红色所示:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200424112903651.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzMyNzQ0MDA1,size_16,color_FFFFFF,t_70

基本命令

run 运行程序®
continue 中断后继续运行到下一个断点©,等同(fg)
step 单步执行,进入函数(s)
next 单步执行(n)
return 函数未执行完,忽略未执行的语句,返回(ret)
finish 函数执行完毕返回
backtrace 显示栈桢 (bt)
list 显示源码(l)
pwd 当前的工作目录
cd 切换当前工作目录
print 打印数值(p)
break 打断点(b)
delete 删除断点
clear 删除断点
disable 使断点失效
enable 使断点生效
info 查看信息
info breakpoints 查看目前所有断点信息
info stack 查看此刻函数栈信息
info locals 查看当前函数中所有局部变量以及其值
set args 设置运行前参数
info args 查看此刻函数栈入参信息
set x=1 设置变量或表达式值
help 查看帮助文档
sysbol-file 加载符号表信息
until 结束当前循环(u)
quit 退出gdb

GDB 一些实用的设置

  • 打印设置
    set print null-stop on/off 如果打开了这个选项,那么当显示字符串时,遇到结束符则停止显示。这个选项默认为off
    set print element 0 输出完整的字符串
    set print pretty on/off 设置GDB打印结构体,每行一个成员,并且有相应的缩进,缺省是关闭的
    set print array on/off 数组显示时,每个元素占一行,如果不打开的话,每个元素则以逗号分隔,默认是关闭set print array-indexes on/off 数组显示时,是否展示下标
    set print sevenbit-strings <on/off> 设置字符显示,是否按“/nnn”的格式显示,如果打开,则字符串或字符数据按

  • 日志保存设置
    使用GDB的记录功能,可以将调试信息放在日志文本中,便于记录以及提供开发人员定位。
    set logging on
    打开记录功能。
    set logging off
    关闭记录功能。
    set logging file
    改变当前日志文件的名称。默认的日志文件是`gdb.txt’。
    set logging overwrite [on|off]
    默认情况下,GDB会添加到日志文件中。如果你set logging on想复盖掉日志文件, 就设置overwrite。
    set logging redirect [on|off]
    默认情况下,GDB会输出到终端和日志文件。如果你想仅仅输出到日志文件,设置redirect。
    show logging
    显示日志设置的当前值

  • 多进程设置
    GDB 没有对多进程程序调试提供直接支持。例如,使用GDB调试某个进程,如果该进程fork了子进程,GDB会继续调试该进程,子进程会不受干扰地运行下去。如果你事先在子进程代码里设定了断点,子进程会收到SIGTRAP信号并终止。
    缺省方式:fork/vfork之后,GDB仍然调试父进程,与子进程不相关,GDB>v7.0支持多进程分别以及同时调试。
    show follow-fork-mode:查看当前GDB多进程跟踪模式的设置
    set follow-fork-mode [parent|child] :默认是parent
    所以如果想要调试子进程,进入gdb后设置set follow-fork-mode child,然后设置子进程的断点
    detach-on-fork mode [on|off] on: 只调试父进程或子进程的其中一个(根据follow-fork-mode来决定),这是默认的模式。
    off: 父子进程都在gdb的控制之下,其中一个进程正常调试(根据follow-fork-mode来决定),另一个进程会被设置为暂停状态。
    parent on 只调试主进程(GDB默认)
    child on 只调试子进程
    parent off 同时调试两个进程,gdb主进程,子进程block在fork位置
    child off 同时调试两个进程,gdb子进程,主进程block在fork位置

  • 多线程设置
    show scheduler-locking
    off:不锁定任何线程,所有线程可以在任何时间运行,这是默认值。
    on:只有当前被调试程序会执行,锁定其他线程。
    step:该模式是对single-stepping模式的优化。此模式会阻止其他线程在当前线程单步调试时,抢占当前线。因此调试的焦点不会被以外的改变。其他线程不可能抢占当前的调试线程。其他线程只有下列情况下会重新获得运行的机会:
    1.next一个函数调用
    2.使用诸如continue\until\finish命令
    3.其他线程遇到设置好的断点,当程序继续运行的时候如果有断点,那么就把所有的线程都停下来,直到你指定某个线程继续执行(thread thread_no apply continue),但是如果直接在当前线程执行continue的话,默认是会启动所有线程。这种模式有一种副作用,如果多个线程都断在同一个函数,这时候调试会出问题。
    thread find [regexp],其中regexp可以是线程的systag,例如,LWP 25582中的25582,或线程名(系统定义的或用户自定义的),之后使用thread thread_no apply threadID continue。

  • gdb不停模式设置
    set non-stop on|off 默认为off,表示当一个线程停止时其他线程全部停止。在on模式下,当一个线程停止时,
    其他线程可以继续运行。独立地对每个线程进行操作,在需要的时候停止或自由运行,除
    了断点有关的线程会被停下来,其他线程会执行。
    set pagination on|off 在使用backtrace时,在分页时是否停止,off停止,on继续
    set target-async on|off 同步和异步。on同步,gdb在输出提示符之前等待程序报告一些线程已经终止的信息。
    off异步的则是直接返回。

  • 启动参数
    调试未启动的进程且不带参数
    gdb core
    run
    调试未启动的进程且带参数
    gdb core
    set args $1 $1
    run
    调试已经崩溃的进程
    gdb core coredump文件
    调试已经启动的进程:
    a.gdb
    shell ps –ef | grep core
    attach PID
    b.gdb –p pidof core
    读取文件描述符:
    symbols XXX.sym
    使用源码显示模式:
    gdb –tui core

  • watch的使用
    a. 整形变量:int i; watch i;
    b. 指针类型: char *p; watch p, watch *p; watch p 是查看 *(&p), 是p 变量本身,watch (*p) 是 p 所指的内存的
    内容。
    c. watch 一个数组或内存区间 char buf[128], watch buf, 是对buf 的128个数据进行了监视.。
    watch :为表达式(变量)expr设置一个观察点。一旦表达式值有变化时,马上停住程序。
      rwatch :当表达式(变量)expr被读时,停住程序。
      awatch :当表达式(变量)的值被读或被写时,停住程序。
      info watchpoints:列出当前所设置了的所有观察点。

  • checkpoint
      在Linux,gdb支持保留程序在某个时候的快照,除了进程号和已经输出的内容,所有状态恢复到快照状态。
      通过以下命令实现快照。
      checkpoing: 生成当前状态的快照类似shell命令(gcore 进程名)
      info checkpoint:显示快照信息
      restart checkpoint-id:恢复到某个checkpoint
      delete checkpoint checkpoint-id:删除某个checkpoint

  • 调试已经在运行的程序:
    attach pid:从ps获得进程号,通过attach命令连接到该进程。attach一个进程后,gdb首先stop该进程,这样就可以设置断点,执行step、continue等命令;如果执行r命令,会杀掉原来的进程。
    detach:释放该进程,原进程会继续执行。

  • 查看线程有无死锁问题
    ps
    pstree -p core | grep co*
    pstack 进程号(多次使用)
    Linux C/C++代码 使用gdb进行coredump调试Linux C/C++代码 使用gdb进行coredump调试

  • 查看具体是那个线程死锁问题:
    1.info threads 查看所有线程大概信息
    thread n 切换到某个线程
    bt(where) 打印线程堆栈信息
    2.thread apply all bt 打印所有线程堆栈信息
    线程比较多,也可以搜索线程, thread find 线程名字

调试案列(容器调试)

容器里面数据的,第二张使用.gdbinit脚本后打印效果。

Linux C/C++代码 使用gdb进行coredump调试
Linux C/C++代码 使用gdb进行coredump调试

  1. gdbinit文件重命名为.gdbinit

  2. gdb起来后,执行source ,souce .gdbinit所在的绝对路径

std::vector pvector
std::list plist or plist_member command
std::map<T,T> pmap or pmap_member command
std::multimap<T,T> pmap or pmap_member command
std::set pset command
std::multiset pset command
std::deque pdequeue command
std::stack pstack command
std::queue pqueue command
std::priority_queue ppqueue command
std::bitset pbitset command
std::string pstring command
std::widestring pwstring command

gdbinit文件源码:

#                                                                                                        
# STL GDB evaluators/views/utilities - 1.03
#
# The new GDB commands:
# are entirely non instrumental
# do not depend on any "inline"(s) - e.g. size(), [], etc
# are extremely tolerant to debugger settings
#
# This file should be "included" in .gdbinit as following:
# source stl-views.gdb or just paste it into your .gdbinit file
#
# The following STL containers are currently supported:
#
# std::vector<T> -- via pvector command
# std::list<T> -- via plist or plist_member command
# std::map<T,T> -- via pmap or pmap_member command
# std::multimap<T,T> -- via pmap or pmap_member command
# std::set<T> -- via pset command
# std::multiset<T> -- via pset command
# std::deque<T> -- via pdequeue command
# std::stack<T> -- via pstack command
# std::queue<T> -- via pqueue command
# std::priority_queue<T> -- via ppqueue command
# std::bitset<n> -- via pbitset command
# std::string -- via pstring command
# std::widestring -- via pwstring command
#
# The end of this file contains (optional) C++ beautifiers
# Make sure your debugger supports $argc
#
# Simple GDB Macros writen by Dan Marinescu (H-PhD) - License GPL
# Inspired by intial work of Tom Malnar,
# Tony Novac (PhD) / Cornell / Stanford,
# Gilad Mishne (PhD) and Many Many Others.
# Contact: [email protected] (Subject: STL)
#
# Modified to work with g++ 4.3 by Anders Elton
# Also added _member functions, that instead of printing the entire class in map, prints a member.

set auto-load safe-path /

#
# std::vector<>
#

define pvector

if $argc == 0
help pvector
else
set $size = $arg0._M_impl._M_finish - $arg0._M_impl._M_start
set $capacity = $arg0._M_impl._M_end_of_storage - $arg0._M_impl._M_start
set $size_max = $size - 1
end
if $argc == 1
set $i = 0
while $i < $size
printf "elem[%u]: ", $i
p *($arg0._M_impl._M_start + $i)
set $i++
end
end
if $argc == 2
set $idx = $arg1
if $idx < 0 || $idx > $size_max
printf "idx1, idx2 are not in acceptable range: [0..%u].\n", $size_max
else
printf "elem[%u]: ", $idx
p *($arg0._M_impl._M_start + $idx)
end
end
if $argc == 3
set $start_idx = $arg1
set $stop_idx = $arg2
if $start_idx > $stop_idx
set $tmp_idx = $start_idx
set $start_idx = $stop_idx
set $stop_idx = $tmp_idx
end
if $start_idx < 0 || $stop_idx < 0 || $start_idx > $size_max || $stop_idx > $size_max
printf "idx1, idx2 are not in acceptable range: [0..%u].\n", $size_max
else
set $i = $start_idx
while $i <= $stop_idx
printf "elem[%u]: ", $i
p *($arg0._M_impl._M_start + $i)
set $i++
end
end
end
if $argc > 0
printf "Vector size = %u\n", $size
printf "Vector capacity = %u\n", $capacity
printf "Element "
whatis $arg0._M_impl._M_start
end
end

document pvector
Prints std::vector<T> information.
Syntax: pvector <vector> <idx1> <idx2>
Note: idx, idx1 and idx2 must be in acceptable range [0..<vector>.size()-1].
Examples:
pvector v - Prints vector content, size, capacity and T typedef
pvector v 0 - Prints element[idx] from vector
pvector v 1 2 - Prints elements in range [idx1..idx2] from vector
end

#
# std::list<>
#

define plist

if $argc == 0
help plist
else
set $head = &$arg0._M_impl._M_node
set $current = $arg0._M_impl._M_node._M_next
set $size = 0
while $current != $head
if $argc == 2
printf "elem[%u]: ", $size
p *($arg1*)($current + 1)
end
if $argc == 3
if $size == $arg2
printf "elem[%u]: ", $size
p *($arg1*)($current + 1)
end
end
set $current = $current._M_next
set $size++
end
printf "List size = %u \n", $size
if $argc == 1
printf "List "
whatis $arg0
printf "Use plist <variable_name> <element_type> to see the elements in the list.\n"
end
end
end

document plist
Prints std::list<T> information.
Syntax: plist <list> <T> <idx>: Prints list size, if T defined all elements or just element at idx
Examples:
plist l - prints list size and definition
plist l int - prints all elements and list size
plist l int 2 - prints the third element in the list (if exists) and list size
end

define plist_member
if $argc == 0
help plist_member
else
set $head = &$arg0._M_impl._M_node
set $current = $arg0._M_impl._M_node._M_next
set $size = 0
while $current != $head
if $argc == 3
printf "elem[%u]: ", $size
p (*($arg1*)($current + 1)).$arg2
end
if $argc == 4
if $size == $arg3
printf "elem[%u]: ", $size
p (*($arg1*)($current + 1)).$arg2
end
end
set $current = $current._M_next
set $size++
end
printf "List size = %u \n", $size
if $argc == 1
printf "List "
whatis $arg0
printf "Use plist_member <variable_name> <element_type> <member> to see the elements in the list.\n"
end
end
end

document plist_member
Prints std::list<T> information.
Syntax: plist <list> <T> <idx>: Prints list size, if T defined all elements or just element at idx
Examples:
plist_member l int member - prints all elements and list size
plist_member l int member 2 - prints the third element in the list (if exists) and list size
end


#
# std::map and std::multimap
#

define pmap

if $argc == 0
help pmap
else
set $tree = $arg0
set $i = 0
set $node = $tree._M_t._M_impl._M_header._M_left
set $end = $tree._M_t._M_impl._M_header
set $tree_size = $tree._M_t._M_impl._M_node_count
if $argc == 1
printf "Map "
whatis $tree
printf "Use pmap <variable_name> <left_element_type> <right_element_type> to see the elements in the map.\n"
end
if $argc == 3
while $i < $tree_size
set $value = (void *)($node + 1)
printf "elem[%u].left: ", $i
p *($arg1*)$value
set $value = $value + sizeof($arg1)
printf "elem[%u].right: ", $i
p *($arg2*)$value
if $node._M_right != 0
set $node = $node._M_right
while $node._M_left != 0
set $node = $node._M_left
end
else
set $tmp_node = $node._M_parent
while $node == $tmp_node._M_right
set $node = $tmp_node
set $tmp_node = $tmp_node._M_parent
end
if $node._M_right != $tmp_node
set $node = $tmp_node
end
end
set $i++
end
end
if $argc == 4
set $idx = $arg3
set $ElementsFound = 0
while $i < $tree_size
set $value = (void *)($node + 1)
if *($arg1*)$value == $idx
printf "elem[%u].left: ", $i
p *($arg1*)$value
set $value = $value + sizeof($arg1)
printf "elem[%u].right: ", $i
p *($arg2*)$value
set $ElementsFound++
end
if $node._M_right != 0
set $node = $node._M_right
while $node._M_left != 0
set $node = $node._M_left
end
else
set $tmp_node = $node._M_parent
while $node == $tmp_node._M_right
set $node = $tmp_node
set $tmp_node = $tmp_node._M_parent
end
if $node._M_right != $tmp_node
set $node = $tmp_node
end
end
set $i++
end
printf "Number of elements found = %u\n", $ElementsFound
end
if $argc == 5
set $idx1 = $arg3
set $idx2 = $arg4
set $ElementsFound = 0
while $i < $tree_size
set $value = (void *)($node + 1)
set $valueLeft = *($arg1*)$value
set $valueRight = *($arg2*)($value + sizeof($arg1))
if $valueLeft == $idx1 && $valueRight == $idx2
printf "elem[%u].left: ", $i
p $valueLeft
printf "elem[%u].right: ", $i
p $valueRight
set $ElementsFound++
end
if $node._M_right != 0
set $node = $node._M_right
while $node._M_left != 0
set $node = $node._M_left
end
else
set $tmp_node = $node._M_parent
while $node == $tmp_node._M_right
set $node = $tmp_node
set $tmp_node = $tmp_node._M_parent
end
if $node._M_right != $tmp_node
set $node = $tmp_node
end
end
set $i++
end
printf "Number of elements found = %u\n", $ElementsFound
end
printf "Map size = %u\n", $tree_size
end
end

document pmap
Prints std::map<TLeft and TRight> or std::multimap<TLeft and TRight> information. Works for std::multimap as well.
Syntax: pmap <map> <TtypeLeft> <TypeRight> <valLeft> <valRight>: Prints map size, if T defined all elements or just element(s) with val(s)
Examples:
pmap m - prints map size and definition
pmap m int int - prints all elements and map size
pmap m int int 20 - prints the element(s) with left-value = 20 (if any) and map size
pmap m int int 20 200 - prints the element(s) with left-value = 20 and right-value = 200 (if any) and map size
end


define pmap_member
if $argc == 0
help pmap_member
else
set $tree = $arg0
set $i = 0
set $node = $tree._M_t._M_impl._M_header._M_left
set $end = $tree._M_t._M_impl._M_header
set $tree_size = $tree._M_t._M_impl._M_node_count
if $argc == 1
printf "Map "
whatis $tree
printf "Use pmap <variable_name> <left_element_type> <right_element_type> to see the elements in the map.\n"
end
if $argc == 5
while $i < $tree_size
set $value = (void *)($node + 1)
printf "elem[%u].left: ", $i
p (*($arg1*)$value).$arg2
set $value = $value + sizeof($arg1)
printf "elem[%u].right: ", $i
p (*($arg3*)$value).$arg4
if $node._M_right != 0
set $node = $node._M_right
while $node._M_left != 0
set $node = $node._M_left
end
else
set $tmp_node = $node._M_parent
while $node == $tmp_node._M_right
set $node = $tmp_node
set $tmp_node = $tmp_node._M_parent
end
if $node._M_right != $tmp_node
set $node = $tmp_node
end
end
set $i++
end
end
if $argc == 6
set $idx = $arg5
set $ElementsFound = 0
while $i < $tree_size
set $value = (void *)($node + 1)
if *($arg1*)$value == $idx
printf "elem[%u].left: ", $i
p (*($arg1*)$value).$arg2
set $value = $value + sizeof($arg1)
printf "elem[%u].right: ", $i
p (*($arg3*)$value).$arg4
set $ElementsFound++
end
if $node._M_right != 0
set $node = $node._M_right
while $node._M_left != 0
set $node = $node._M_left
end
else
set $tmp_node = $node._M_parent
while $node == $tmp_node._M_right
set $node = $tmp_node
set $tmp_node = $tmp_node._M_parent
end
if $node._M_right != $tmp_node
set $node = $tmp_node
end
end
set $i++
end
printf "Number of elements found = %u\n", $ElementsFound
end
printf "Map size = %u\n", $tree_size
end
end

document pmap_member
Prints std::map<TLeft and TRight> or std::multimap<TLeft and TRight> information. Works for std::multimap as well.
Syntax: pmap <map> <TtypeLeft> <TypeRight> <valLeft> <valRight>: Prints map size, if T defined all elements or just element(s) with val(s)
Examples:
pmap_member m class1 member1 class2 member2 - prints class1.member1 : class2.member2
pmap_member m class1 member1 class2 member2 lvalue - prints class1.member1 : class2.member2 where class1 == lvalue
end


#
# std::set and std::multiset
#

define pset

if $argc == 0
help pset
else
set $tree = $arg0
set $i = 0
set $node = $tree._M_t._M_impl._M_header._M_left
set $end = $tree._M_t._M_impl._M_header
set $tree_size = $tree._M_t._M_impl._M_node_count
if $argc == 1
printf "Set "
whatis $tree
printf "Use pset <variable_name> <element_type> to see the elements in the set.\n"
end
if $argc == 2
while $i < $tree_size
set $value = (void *)($node + 1)
printf "elem[%u]: ", $i
p *($arg1*)$value
if $node._M_right != 0
set $node = $node._M_right
while $node._M_left != 0
set $node = $node._M_left
end
else
set $tmp_node = $node._M_parent
while $node == $tmp_node._M_right
set $node = $tmp_node
set $tmp_node = $tmp_node._M_parent
end
if $node._M_right != $tmp_node
set $node = $tmp_node
end
end
set $i++
end
end
if $argc == 3
set $idx = $arg2
set $ElementsFound = 0
while $i < $tree_size
set $value = (void *)($node + 1)
if *($arg1*)$value == $idx
printf "elem[%u]: ", $i
p *($arg1*)$value
set $ElementsFound++
end
if $node._M_right != 0
set $node = $node._M_right
while $node._M_left != 0
set $node = $node._M_left
end
else
set $tmp_node = $node._M_parent
while $node == $tmp_node._M_right
set $node = $tmp_node
set $tmp_node = $tmp_node._M_parent
end
if $node._M_right != $tmp_node
set $node = $tmp_node
end
end
set $i++
end
printf "Number of elements found = %u\n", $ElementsFound
end
printf "Set size = %u\n", $tree_size
end
end

document pset
Prints std::set<T> or std::multiset<T> information. Works for std::multiset as well.
Syntax: pset <set> <T> <val>: Prints set size, if T defined all elements or just element(s) having val
Examples:
pset s - prints set size and definition
pset s int - prints all elements and the size of s
pset s int 20 - prints the element(s) with value = 20 (if any) and the size of s
end



#
# std::dequeue
#

define pdequeue

if $argc == 0
help pdequeue
else
set $size = 0
set $start_cur = $arg0._M_impl._M_start._M_cur
set $start_last = $arg0._M_impl._M_start._M_last
set $start_stop = $start_last
while $start_cur != $start_stop
p *$start_cur
set $start_cur++
set $size++
end
set $finish_first = $arg0._M_impl._M_finish._M_first
set $finish_cur = $arg0._M_impl._M_finish._M_cur
set $finish_last = $arg0._M_impl._M_finish._M_last
if $finish_cur < $finish_last
set $finish_stop = $finish_cur
else
set $finish_stop = $finish_last
end
while $finish_first != $finish_stop
p *$finish_first
set $finish_first++
set $size++
end
printf "Dequeue size = %u\n", $size
end
end

document pdequeue
Prints std::dequeue<T> information.
Syntax: pdequeue <dequeue>: Prints dequeue size, if T defined all elements
Deque elements are listed "left to right" (left-most stands for front and right-most stands for back)
Example:
pdequeue d - prints all elements and size of d
end



#
# std::stack
#

define pstack

if $argc == 0
help pstack
else
set $start_cur = $arg0.c._M_impl._M_start._M_cur
set $finish_cur = $arg0.c._M_impl._M_finish._M_cur
set $size = $finish_cur - $start_cur
set $i = $size - 1
while $i >= 0
p *($start_cur + $i)
set $i--
end
printf "Stack size = %u\n", $size
end
end

document pstack
Prints std::stack<T> information.
Syntax: pstack <stack>: Prints all elements and size of the stack
Stack elements are listed "top to buttom" (top-most element is the first to come on pop)
Example:
pstack s - prints all elements and the size of s
end



#
# std::queue
#

define pqueue

if $argc == 0
help pqueue
else
set $start_cur = $arg0.c._M_impl._M_start._M_cur
set $finish_cur = $arg0.c._M_impl._M_finish._M_cur
set $size = $finish_cur - $start_cur
set $i = 0
while $i < $size
p *($start_cur + $i)
set $i++
end
printf "Queue size = %u\n", $size
end
end

document pqueue
Prints std::queue<T> information.
Syntax: pqueue <queue>: Prints all elements and the size of the queue
Queue elements are listed "top to bottom" (top-most element is the first to come on pop)
Example:
pqueue q - prints all elements and the size of q
end



#
# std::priority_queue
#

define ppqueue

if $argc == 0
help ppqueue
else
set $size = $arg0.c._M_impl._M_finish - $arg0.c._M_impl._M_start
set $capacity = $arg0.c._M_impl._M_end_of_storage - $arg0.c._M_impl._M_start
set $i = $size - 1
while $i >= 0
p *($arg0.c._M_impl._M_start + $i)
set $i--
end
printf "Priority queue size = %u\n", $size
printf "Priority queue capacity = %u\n", $capacity
end
end

document ppqueue
Prints std::priority_queue<T> information.
Syntax: ppqueue <priority_queue>: Prints all elements, size and capacity of the priority_queue
Priority_queue elements are listed "top to buttom" (top-most element is the first to come on pop)
Example:
ppqueue pq - prints all elements, size and capacity of pq
end



#
# std::bitset
#

define pbitset

if $argc == 0
help pbitset
else
p /t $arg0._M_w
end
end

document pbitset
Prints std::bitset<n> information.
Syntax: pbitset <bitset>: Prints all bits in bitset
Example:
pbitset b - prints all bits in b
end



#
# std::string
#

define pstring

if $argc == 0
help pstring
else
printf "String \t\t\t= \"%s\"\n", $arg0._M_data()
printf "String size/length \t= %u\n", $arg0._M_rep()._M_length
printf "String capacity \t= %u\n", $arg0._M_rep()._M_capacity
printf "String ref-count \t= %d\n", $arg0._M_rep()._M_refcount
end
end

document pstring
Prints std::string information.
Syntax: pstring <string>
Example:
pstring s - Prints content, size/length, capacity and ref-count of string s
end

#
# std::wstring
#

define pwstring

if $argc == 0
help pwstring
else
call printf("WString \t\t= \"%ls\"\n", $arg0._M_data())
printf "WString size/length \t= %u\n", $arg0._M_rep()._M_length
printf "WString capacity \t= %u\n", $arg0._M_rep()._M_capacity
printf "WString ref-count \t= %d\n", $arg0._M_rep()._M_refcount
end
end

document pwstring
Prints std::wstring information.
Syntax: pwstring <wstring>
Example:
pwstring s - Prints content, size/length, capacity and ref-count of wstring s
end

#
# C++ related beautifiers (optional)
#

set print pretty on

set print object on
set print static-members on
set print vtbl on
set print demangle on
set demangle-style gnu-v3
set print sevenbit-strings off
  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

  • 11

  • 12

  • 13

  • 14

  • 15

  • 16

  • 17

  • 18

  • 19

  • 20

  • 21

  • 22

  • 23

  • 24

  • 25

  • 26

  • 27

  • 28

  • 29

  • 30

  • 31

  • 32

  • 33

  • 34

  • 35

  • 36

  • 37

  • 38

  • 39

  • 40

  • 41

  • 42

  • 43

  • 44

  • 45

  • 46

  • 47

  • 48

  • 49

  • 50

  • 51

  • 52

  • 53

  • 54

  • 55

  • 56

  • 57

  • 58

  • 59

  • 60

  • 61

  • 62

  • 63

  • 64

  • 65

  • 66

  • 67

  • 68

  • 69

  • 70

  • 71

  • 72

  • 73

  • 74

  • 75

  • 76

  • 77

  • 78

  • 79

  • 80

  • 81

  • 82

  • 83

  • 84

  • 85

  • 86

  • 87

  • 88

  • 89

  • 90

  • 91

  • 92

  • 93

  • 94

  • 95

  • 96

  • 97

  • 98

  • 99

  • 100

  • 101

  • 102

  • 103

  • 104

  • 105

  • 106

  • 107

  • 108

  • 109

  • 110

  • 111

  • 112

  • 113

  • 114

  • 115

  • 116

  • 117

  • 118

  • 119

  • 120

  • 121

  • 122

  • 123

  • 124

  • 125

  • 126

  • 127

  • 128

  • 129

  • 130

  • 131

  • 132

  • 133

  • 134

  • 135

  • 136

  • 137

  • 138

  • 139

  • 140

  • 141

  • 142

  • 143

  • 144

  • 145

  • 146

  • 147

  • 148

  • 149

  • 150

  • 151

  • 152

  • 153

  • 154

  • 155

  • 156

  • 157

  • 158

  • 159

  • 160

  • 161

  • 162

  • 163

  • 164

  • 165

  • 166

  • 167

  • 168

  • 169

  • 170

  • 171

  • 172

  • 173

  • 174

  • 175

  • 176

  • 177

  • 178

  • 179

  • 180

  • 181

  • 182

  • 183

  • 184

  • 185

  • 186

  • 187

  • 188

  • 189

  • 190

  • 191

  • 192

  • 193

  • 194

  • 195

  • 196

  • 197

  • 198

  • 199

  • 200

  • 201

  • 202

  • 203

  • 204

  • 205

  • 206

  • 207

  • 208

  • 209

  • 210

  • 211

  • 212

  • 213

  • 214

  • 215

  • 216

  • 217

  • 218

  • 219

  • 220

  • 221

  • 222

  • 223

  • 224

  • 225

  • 226

  • 227

  • 228

  • 229

  • 230

  • 231

  • 232

  • 233

  • 234

  • 235

  • 236

  • 237

  • 238

  • 239

  • 240

  • 241

  • 242

  • 243

  • 244

  • 245

  • 246

  • 247

  • 248

  • 249

  • 250

  • 251

  • 252

  • 253

  • 254

  • 255

  • 256

  • 257

  • 258

  • 259

  • 260

  • 261

  • 262

  • 263

  • 264

  • 265

  • 266

  • 267

  • 268

  • 269

  • 270

  • 271

  • 272

  • 273

  • 274

  • 275

  • 276

  • 277

  • 278

  • 279

  • 280

  • 281

  • 282

  • 283

  • 284

  • 285

  • 286

  • 287

  • 288

  • 289

  • 290

  • 291

  • 292

  • 293

  • 294

  • 295

  • 296

  • 297

  • 298

  • 299

  • 300

  • 301

  • 302

  • 303

  • 304

  • 305

  • 306

  • 307

  • 308

  • 309

  • 310

  • 311

  • 312

  • 313

  • 314

  • 315

  • 316

  • 317

  • 318

  • 319

  • 320

  • 321

  • 322

  • 323

  • 324

  • 325

  • 326

  • 327

  • 328

  • 329

  • 330

  • 331

  • 332

  • 333

  • 334

  • 335

  • 336

  • 337

  • 338

  • 339

  • 340

  • 341

  • 342

  • 343

  • 344

  • 345

  • 346

  • 347

  • 348

  • 349

  • 350

  • 351

  • 352

  • 353

  • 354

  • 355

  • 356

  • 357

  • 358

  • 359

  • 360

  • 361

  • 362

  • 363

  • 364

  • 365

  • 366

  • 367

  • 368

  • 369

  • 370

  • 371

  • 372

  • 373

  • 374

  • 375

  • 376

  • 377

  • 378

  • 379

  • 380

  • 381

  • 382

  • 383

  • 384

  • 385

  • 386

  • 387

  • 388

  • 389

  • 390

  • 391

  • 392

  • 393

  • 394

  • 395

  • 396

  • 397

  • 398

  • 399

  • 400

  • 401

  • 402

  • 403

  • 404

  • 405

  • 406

  • 407

  • 408

  • 409

  • 410

  • 411

  • 412

  • 413

  • 414

  • 415

  • 416

  • 417

  • 418

  • 419

  • 420

  • 421

  • 422

  • 423

  • 424

  • 425

  • 426

  • 427

  • 428

  • 429

  • 430

  • 431

  • 432

  • 433

  • 434

  • 435

  • 436

  • 437

  • 438

  • 439

  • 440

  • 441

  • 442

  • 443

  • 444

  • 445

  • 446

  • 447

  • 448

  • 449

  • 450

  • 451

  • 452

  • 453

  • 454

  • 455

  • 456

  • 457

  • 458

  • 459

  • 460

  • 461

  • 462

  • 463

  • 464

  • 465

  • 466

  • 467

  • 468

  • 469

  • 470

  • 471

  • 472

  • 473

  • 474

  • 475

  • 476

  • 477

  • 478

  • 479

  • 480

  • 481

  • 482

  • 483

  • 484

  • 485

  • 486

  • 487

  • 488

  • 489

  • 490

  • 491

  • 492

  • 493

  • 494

  • 495

  • 496

  • 497

  • 498

  • 499

  • 500

  • 501

  • 502

  • 503

  • 504

  • 505

  • 506

  • 507

  • 508

  • 509

  • 510

  • 511

  • 512

  • 513

  • 514

  • 515

  • 516

  • 517

  • 518

  • 519

  • 520

  • 521

  • 522

  • 523

  • 524

  • 525

  • 526

  • 527

  • 528

  • 529

  • 530

  • 531

  • 532

  • 533

  • 534

  • 535

  • 536

  • 537

  • 538

  • 539

  • 540

  • 541

  • 542

  • 543

  • 544

  • 545

  • 546

  • 547

  • 548

  • 549

  • 550

  • 551

  • 552

  • 553

  • 554

  • 555

  • 556

  • 557

  • 558

  • 559

  • 560

  • 561

  • 562

  • 563

  • 564

  • 565

  • 566

  • 567

  • 568

  • 569

  • 570

  • 571

  • 572

  • 573

  • 574

  • 575

  • 576

  • 577

  • 578

  • 579

  • 580

  • 581

  • 582

  • 583

  • 584

  • 585

  • 586

  • 587

  • 588

  • 589

  • 590

  • 591

  • 592

  • 593

  • 594

  • 595

  • 596

  • 597

  • 598

  • 599

  • 600

  • 601

  • 602

  • 603

  • 604

  • 605

  • 606

  • 607

  • 608

  • 609

  • 610

  • 611

  • 612

  • 613

  • 614

  • 615

  • 616

  • 617

  • 618

  • 619

  • 620

  • 621

  • 622

  • 623

  • 624

  • 625

  • 626

  • 627

  • 628

  • 629

  • 630

  • 631

  • 632

  • 633

  • 634

  • 635

  • 636

  • 637

  • 638

  • 639

  • 640

  • 641

  • 642

  • 643

  • 644

  • 645

  • 646

  • 647

  • 648

  • 649

  • 650

  • 651

  • 652

  • 653

  • 654

  • 655

  • 656

  • 657

  • 658

  • 659

  • 660

  • 661

  • 662

  • 663

  • 664

  • 665

  • 666

  • 667

  • 668

  • 669

  • 670

  • 671

  • 672

  • 673

  • 674

  • 675

  • 676

  • 677

  • 678

  • 679

  • 680

  • 681

  • 682

  • 683

  • 684

  • 685

  • 686

  • 687

  • 688

  • 689

  • 690

  • 691

  • 692

  • 693

  • 694

  • 调试list
    如果不使用此工具,打印list中值:
    1.先打印第一个头节点, p oParkingLotList1.m_oParkingLotIDList._M_impl._M_node
    2.在根据M_next依次打印数值
    p *oParkingLotList1.m_oParkingLotIDList._M_impl._M_node._M_next._M_next
    使用工具打印:plist oParkingLotList1.m_oParkingLotIDList int
    Linux C/C++代码 使用gdb进行coredump调试

  • 调试map:
    pmap [map类对象名] [key字段类型] [第二个元素的类型] [index]
    pmap oMap
    pmap oMap int int 20
    pmap oParkingInfoContainerMap int ParkingContainerVector

然后可以使用print 进行值打印:
其中elem[0].left表示map该map表节点的键值,elem[0].right表示该map表节点的第二个元素的值。最后的Map size表示目前map表中共有多少个元素

调试案列(反汇编查看DUMP信息)

在函数调用和系统调用时,需要先将参数压入栈,然后被调用函数再从相应的寄存器获取参数值,存储在被调用函数的栈中,所以被调用函数对参数做出的改变并不会修改主函数的数值,因为他们在不同的栈中。函数的参数存入栈的顺序是从右到左,如果是调用函数main(int argc ,char *argv[]),则是先将argv压入栈,然后再将argc压入栈(目前平台如此)。
一般寄存器:ax、bx、cx、dxax:累积暂存器,
bx:基底暂存器
cx:计数暂存器
dx:资料暂存器

索引暂存器:si、disi:来源索引暂存器
di:目的索引暂存器
sp:堆栈指针寄存器,只能访问栈顶,指向当前栈顶
bp:基指针寄存器,他可以直接访问存取堆栈中的数据。

rip 指令寄存器,指向当前执行的代码位置
rax、rcx、rdx、rbx:是ax,bx,cx,dx的扩展rsi、rdi、rsp、rbp:是si,di,sp,bp的扩展
可以把这些寄存器当作变量看待,可以重复赋值,