gcc_g++_gdb
2、简述GDB常见的调试命令,什么是条件断点,多进程下如何调试。¶
GDB调试:gdb调试的是可执行文件,在gcc编译时加入 -g ,告诉gcc在编译时加入调试信息,这样gdb 才能调试这个被编译的文件 gcc -g tesst.c -o test GDB命令格式:
- quit:退出gdb,结束调试
- list:查看程序源代码 list 5,10:显示5到10行的代码 list test.c:5, 10: 显示源文件5到10行的代码,在调试多个文件时使用 list get_sum: 显示get_sum函数周围的代码 list test.c get_sum: 显示源文件get_sum函数周围的代码,在调试多个文件时使用
- reverse-search:字符串用来从当前行向前查找第一个匹配的字符串
- run:程序开始执行
- help list/all:查看帮助信息
- break:设置断点 break 7:在第七行设置断点 break get_sum:以函数名设置断点 break 行号或者函数名 if 条件:以条件表达式设置断点
- watch 条件表达式:条件表达式发生改变时程序就会停下来
- next:继续执行下一条语句 ,会把函数当作一条语句执行
- step:继续执行下一条语句,会跟踪进入函数,一次一条的执行函数内的代码
- continue:继续运行到下一个断点
条件断点:break if 条件 以条件表达式设置断点
多进程下如何调试:用set follow-fork-mode child 调试子进程 或者set follow-fork-mode parent 调试父进程
12、说说静态库和动态库怎么制作及如何使用,区别是什么¶
静态库的制作:
静态库的使用:
gcc main.c -lhello -o staticLibrary//main.c和hello静态库链接,生成staticLibrary执行
文件
/*
main.c:是指main主函数
-lhello:是我们生成的.a 文件砍头去尾(lib不要 .a也不要)前面加-l
-L:是指告诉gcc编译器先从-L指定的路径去找静态库,默认是从/usr/lib/ 或者
/usr/local/lib/ 去找。
./:是指当前路径的意思
staticLibrary:是最后想生成的文件名(这里可随意起名字)
*/
动态库的制作:
gcc -fPIC a.c b.c c.c -c
gcc -shared -o libmytest.so a.o b.o c.o
gcc -shared -fPIC hello.c -o libhello.so
-shared 指定生成动态库
-fPIC :fPIC选项作用于编译阶段,在生成目标文件时就得使用该选项,以生成位置无关的代码。
动态库的使用:
gcc main.c -L./ -lhello -o dynamicDepot
/*
main.c:是指main主函数
-lhello:是我们生成的.so 文件砍头去尾(lib不要 .so也不要)前面加-l
-L:是指告诉gcc编译器先从-L指定的路径去找动态库,默认是从/usr/lib/ 或者
/usr/local/lib/ 去找。
./:是指当前路径的意思
dynamicDepot:是最后想生成的文件名(这里可随意起名字)
*/
区别:
- 静态库代码装载的速度快,执行速度略比动态库快。
-
动态库更加节省内存,可执行文件体积比静态库小很多。
-
静态库是在编译时加载,动态库是在运行时加载。
- 生成的静态链接库,Windows下以.lib为后缀,Linux下以.a为后缀。 生成的动态链接库,Windows下以.dll为后缀,Linux下以.so为后缀。
14、gdb调试¶
1.启动gdb
start -- 只执行一步,停在第一行执行语句
n -- next
s -- step(单步) -- 可以进入到函数体内部
c - continue -- 直接停在断点的位置
2. 查看代码:
l -- list,查看所在的源代码行附近的内容
l 10(函数名)
l filename:行号(函数名)
3. 设置断点:
(断点需要在程序start后才能加)
设置当前文件断点:
b -- break
b 10(函数名)
设置指定文件断点:
b fileName:行号(函数名)
设置条件断点:
b 10 if value==19
删除断点:
delete -- del - d
d 断点的编号
获取编号: info -- i
info b
4. 查看设置的断点
5. 开始 执行gdb调试
执行一步操作:
继续执行:
执行多步, 直接停在断点处:
5. 单步调试
进入函数体内部: s
从函数体内部跳出: finish
不进入函数体内部:
n
退出当前循环: u
6. 查看变量的值: p -- print
7. 查看变量的类型: ptype 变量名
8. 设置变量的值: set var 变量名 = 赋值;没办法接收函数的返回值,直接p function()打印返回值
9. 设置追踪变量
display
取消追踪变量
undisplay 编号
获取编号: info display
10. 退出gdb调试
quit
使用场景
程序编译无误,但是有逻辑错误
使用文字终端(shell),实现一个单步调试的功能
生成可执行文件之前必须加参数 -g
gcc hello.c -o hello -g
启动gdb调试
gdb + 可执行文件 (如:gdb hello)
gdb相关命令
l(list) --> 列出文件的代码清单
l + 行号(l 32) --> 代码从第32行开始显示
b(break)--> 设置断点
b + 行号(b 12)--> 在第12行设置断点
b + 行号(2) + 条件(if i=5) --> 在第2行设置断点,只有i等于5时生效
info b(break)--> 查看断点信息
info source --> 查看当前源代码文件的路径 info sources查看全部源代码
r(run)--> 启动或重新启动程序,可加参数,会停在第一个断点处
start --> 单步执行,运行程序,停在第一行执行语句
disable/enable + 断点号 --> 设置断点是否有效
d(delete)+ 断点号 --> 删除指定断点号对应的断点
p(print) + 变量名 --> 打印变量值
display + 变量名 --> 追踪变量
之后每执行一步,该变量值都会被打印出来
undisplay + 变量名编号 --> 取消跟踪
n(next)--> 下一行(不会进入到函数体内部)
s(step)--> 下一步(会进入到函数体内部)
ptyte + 变量名 --> 查看变量的类型
(fin)finish --> 结束当前函数,返回到函数调用点
set --> 设置变量的值 set var n=100
q(quit) --> 退出gdb