Linux C/C++代码 使用gdb进行coredump调试
Posted 程序员森林
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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文件是什么?
产生根因:
如果信号均是采用默认操作,以下列的几种信号,它们在发生时会产生 core dump,如下图:
内存访问越界 (数组越界、字符串无 结束符、字符串读写越界)
多线程程序中使用了线程不安全的函数,如不可重入函数(函数体内使用了静态的数据结构,函数体内调用 标准I/O函数,函数体内调用了malloc()或者free()函数)
多线程读写的数据未加锁保护(临界区资源需要互斥访问)
进程退出都会产生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.使用诸如continueuntilfinish命令
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 –ppidof core
读取文件描述符:
symbols XXX.sym
使用源码显示模式:
gdb –tui corewatch的使用
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 进程号(多次使用)查看具体是那个线程死锁问题:
1.info threads 查看所有线程大概信息
thread n 切换到某个线程
bt(where) 打印线程堆栈信息
2.thread apply all bt 打印所有线程堆栈信息
线程比较多,也可以搜索线程, thread find 线程名字
调试案列(容器调试)
容器里面数据的,第二张使用.gdbinit脚本后打印效果。
gdbinit文件重命名为.gdbinit
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: dan_c_marinescu@yahoo.com (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].
", $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].
", $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
", $size
printf "Vector capacity = %u
", $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
", $size
if $argc == 1
printf "List "
whatis $arg0
printf "Use plist <variable_name> <element_type> to see the elements in the list.
"
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
", $size
if $argc == 1
printf "List "
whatis $arg0
printf "Use plist_member <variable_name> <element_type> <member> to see the elements in the list.
"
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.
"
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
", $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
", $ElementsFound
end
printf "Map size = %u
", $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.
"
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
", $ElementsFound
end
printf "Map size = %u
", $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.
"
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
", $ElementsFound
end
printf "Set size = %u
", $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
", $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
", $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
", $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
", $size
printf "Priority queue capacity = %u
", $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 = "%s"
", $arg0._M_data()
printf "String size/length = %u
", $arg0._M_rep()._M_length
printf "String capacity = %u
", $arg0._M_rep()._M_capacity
printf "String ref-count = %d
", $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 = "%ls"
", $arg0._M_data())
printf "WString size/length = %u
", $arg0._M_rep()._M_length
printf "WString capacity = %u
", $arg0._M_rep()._M_capacity
printf "WString ref-count = %d
", $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调试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的扩展
可以把这些寄存器当作变量看待,可以重复赋值,
以上是关于Linux C/C++代码 使用gdb进行coredump调试的主要内容,如果未能解决你的问题,请参考以下文章