1. from https://blog.youkuaiyun.com/praker/article/details/35340155
MinGW与gdb调试
MinGW(Minamalist GNU For Windows)是个精简的C/C++编译器,它实际上是将经典的开源C语言编译器GCC移植到了Windows下,并且包含了Win32API,因此可以将源代码编译生成Windows下的可执行程序。
一句话来概括,MinGW是GCC的Windows版本
MinGW是开源软件,可以免费使用
MinGW由一个活跃的开源社区在持续维护,不会过时
MinGW使用Windows的C语言运行库,编译出的程序不需要第三方DLL,可以直接在Windows下运行。
对于初学C语言的人来说,MinGW是正合适的编译器,至少黑色的命令提示符界面很有编程的气氛,感觉很酷。
虽然VC6等编译器,只要点击鼠标就可以完成编译,但它会自动生成一大堆工程文件,让初学者摸不着头脑,而MinGW则只会生成一个可执行文件。
总而言之,对于一般人来说,MinGW适合学习C语言时使用,真正工作还是VC6好用。
MinGW安装
标准的MinGW需要连接网络在线安装,
MinGW默认的安装位置是“c:\MinGW”,如果没有特殊需求,默认即可
安装过程中,会弹出“MinGW Installation Manager”安装管理界面,选择需要安装的组件。
右键选择套件,勾选Mark For Installation
左上角菜单Installation选择Apply change就开始安装。
修改环境变量:
选择计算机—属性—高级系统设置—环境变量,在系统变量中找到Path变量,编辑Path变量,在变量值的最前面添加“C:\MinGW\bin;”,这是为了防止和VC/.NET之类的makefile命令冲突。
在开始菜单中点击“运行”,输入cmd,打开命令行,
输入mingw-get,如果弹出Mingw Installation Manager窗口,说明安装正常。
然后关闭Mingw Installation Manager窗口,否则接下来的步骤会报错
在cmd中输入命令mingw-get install gcc,等待一会,gcc就安装成功了,
如果想安装g++,gdb,只要输入命令mingw-get install g++和mingw-get install gdb
使用gdb调试程序:
在cmd当前工作目录写c程序1.cpp,在cmd中输入命令,gcc 1.cpp -g,编译选项-g告诉编译器生成调试信息;
如果要用gdb调试,编译时要加上-g选项,生成调试用的符号表;
第一步:编译程序
gcc 1.cpp -g
生成可执行文件a.exe
第二步:运行gdb
gdb a.exe
这样,gdb在运行时会自动装入刚才生成的可执行程序。
第三步:查看源码
<gdb>l
-
#include <stdio.h>
-
void swap(int a,int b)
-
{
-
int t=a;a=b;b=t;
-
}
-
int main()
-
{
-
int a=3,b=4;
-
swap(3,4);
-
printf("%d %d\n",a,b);
-
return 0;
-
}
这里<gdb>是gdb的提示符,字母l是输入的命令,它是list(列出程序清单)的缩写。
如果用l 15,将会显示第15行(以及它前后的若干行)。所有这些操作,都可以用help list命令来查看;
第四步:加断点并运行
<gdb> b 5
Breakpoint 1 at 0x4016b6:file 1.cpp,line 5.
<gdb> r
Starting Program:D:\\\\4-4\4-4/a.exe
breakpoint 1,swap(a=3,b=4) at 1.cpp;5
其中b命令把断点设在了第5行,r命令运行程序,之后碰到断点并停止。
运行程序的命令是r(run),但会一直执行到程序结束
可以用b(break)命令设置断点让它停下来
第五步:查看调用栈
<gdb> bt
这一步是关键。根据bt命令,调用栈中包含两个栈帧:#0和#1,其中0号是当前栈帧--swap函数,1号是它的“上一个”栈帧--main函数。在这里我们甚至能看到swap函数的返回地址
<gdb> p a
使用p命令可以打印变量值
up命令选择上一栈帧
q命令退出gdb
bt相关命令可以通过help stack来学习
2. from https://blog.youkuaiyun.com/u014023993/article/details/88861115
GDB常用调试指令
CoderAndClimber 2019-04-06 10:13:23 3730 已收藏 10
分类专栏: C++
版权
编译程序时需要加上-g,之后才能用gdb进行调试:gcc -g main.c -o main
常用命令
回车键:重复上一命令
(gdb)help:查看命令帮助,具体命令查询在gdb中输入help + 命令,简写h
(gdb)run:重新开始运行文件(run-text:加载文本文件,run-bin:加载二进制文件),简写r
(gdb)start:单步执行,运行程序,停在第一执行语句
(gdb)list:查看原代码(list-n,从第n行开始查看代码。list+ 函数名:查看具体函数),简写l
(gdb)set:设置变量的值
(gdb)next:单步调试(逐过程,函数直接执行),简写n
(gdb)step:单步调试(逐语句:跳入自定义函数内部执行),简写s
(gdb)backtrace:查看函数的调用的栈帧和层级关系,简写bt
(gdb)frame:切换函数的栈帧,简写f
(gdb)info:查看函数内部局部变量的数值,简写i
(gdb)finish:结束当前函数,返回到函数调用点
(gdb)continue:继续运行,简写c
(gdb)print:打印值及地址,简写p
(gdb)quit:退出gdb,简写q
(gdb)break+num:在第num行设置断点,简写b
b 函数名
b 行号
b 文件名:行号
b 行号 if条件
(gdb)info breakpoints:查看当前设置的所有断点
(gdb)delete breakpoints num:删除第num个断点,简写d
(gdb)display:追踪查看具体变量值
(gdb)undisplay:取消追踪观察变量
(gdb)watch:被设置观察点的变量发生修改时,打印显示
(gdb)i watch:显示观察点
(gdb)enable breakpoints:启用断点
(gdb)disable breakpoints:禁用断点
(gdb)x:查看内存x/20xw 显示20个单元,16进制,4字节每单元
(gdb)run argv[1] argv[2]:调试时命令行传参
(gdb)set follow-fork-mode child#Makefile项目管理:选择跟踪父子进程(fork())
core文件:先用$ ulimit -c 1024 开启core,当程序出错会自动生成core文件。调试时 gdb a.out core
ctrl+c:退出输入
gdb的命令行中输入list或者其简写l可以查看到程序的源码以及行号
如上输入l之后,默认会显示10行源代码,按回车之后会显示接下来的10行,直到文件的末尾。
在gdb命令行环境中输入wi命令,可以让我们进入可视化调试环境,这个环境可以看到源代码,所使用的调试命令与上面讲到的一致。
断点
保存断点到文件:save breakpoint fig.dp
加载断点:gdb hello2 -x fig.dp
打印
p <variable name>/print <variable name>可以查看某一个变量的当前值
print i (p i) 查看变量的值
ptype 查看变量类型
print array 查看数组
print *array@len 查看动态内存
print x=5 改变运行时的数据
print &array 查看数组的地址
core文件
在程序崩溃时,一般会生成一个文件叫core文件。core文件记录的是程序崩溃时的内存映像,并加入调试信息。core文件生成的过程叫做core dump。
首先系统得设置了生成core文件,否则程序奔溃时也不会生成core文件。通过ulimit -a |grep core查看当前的配置。
结果可能如下:core file size (blocks, -c) 0
如果结果如上,那么就需要设置core file的大小:ulimit -c 200
ulimit -c 数字 ,其中数字表示的是Blocks的个数,blocks的大小和系统有关。ulimit -c unlimited 则不限制生成的core文件大小
那么,如果用GDB加载已经生成的core文件呢?
假设测试程序是CoreTest,Core文件名为core.4393,那么通过gdb加载core文件的方式是:
gdb ./CoreTest core.4393
也就是说gdb 程序名 core文件名
参考资料
1. https://yq.aliyun.com/articles/243871
2. https://www.cnblogs.com/tangtangde12580/p/8045980.html
3. https://andrewpqc.github.io/2018/11/25/gcc-and-gdb/
4. https://blog.youkuaiyun.com/u011068702/article/details/53931648
扫描二维码,关注“清远的梦呓”公众号,在手机端查看文章
————————————————
版权声明:本文为优快云博主「CoderAndClimber」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.youkuaiyun.com/u014023993/article/details/88861115
3. from https://zhuanlan.zhihu.com/p/80980060
gdb 根据函数地址 找 对应的函数名
爬山,存储之山
3 人赞同了该文章
debug时候,经常需要查找函数地址,在gdb中可以用 "info address function_name"
(gdb) info address test
Symbol "test" is a function at address 0x9e250
有时候,也会有知道函数地址,反找函数名的需求,在gdb中可以用 "info symbol func_addr"
这个百度不好找,所以分享一下。
(gdb) info symbol 0x9e250
test in section .text
全局变量同样适用。
编辑于 2019-09-05