调试模式
转储文g调试
瞬间静态分析,q程ȝ态?br/>
gdb –core=file
交互调试
调试新进E?br/>
gdb exe
gdb –args exe [args]
调试已经q行的进E?br/> gdb –pid= q程?/p>
内核调试
gdb exe
.
gdb –args exe [args]
.
gdb
file exe
run [args]
.
gdb –args gcc a.c -o a
show args
set args 多次q行讄命o行参?/p>
path directory
.
show paths
.
show environment [varname]
.
set environment varname[=value] 清除或者设|环境变?/p>
l承q入gdb工作目录
改变工作目录
cd dirctory
昄路径
pwd
info terminal
run > a.txt
tty /dev/ttyb
q程调试可用q些辅助?/p>
inferior gdbl护的一pd对象Q每个inf对应一个调试目标进E?/p>
info inferior 昄下层信息
NULL E序没有跑或者已l终?br/>
clone-inferior -copies 2 复制当前下层2?
(gdb) info inferiors
Num Description Executable
* 1 process 10087 /home/gao/code/a
(gdb) clone-inferior -copies 2
Added inferior 2.
Added inferior 3.
(gdb) info inferiors
Num Description Executable
3E序没有跑或者已l终? /home/gao/code/a
2/home/gao/code/a
* 1 process 10087 /home/gao/code/a
(gdb)
切换下程
inferior 2 切换2q个下程?br/> q程h0Q没开始运行?br/> run q行h?/p>
.
增加一个运行下?/p>
add-inferior -exec executeable 增加一个运行下?br/> 比如说调试一个服务端E序Q一个客LE序?/p>
remove-inferior n 删掉一个下?br/>
detach inferior l箋q行 quit
kill inferior 调试q程退了,但是inferiorU录q在?/p>
(gdb) remove-
remove-inferiors remove-symbol-file
(gdb) remove-
remove-inferiors remove-symbol-file
(gdb) remove-
file a.exe 可自行文件和W号文g是一个文?/p>
可自行文件和W号文g分开
exec-file 指定目标文g
.
symbol-file 指定W号文g
run 开始运?
可以支持 run > >> < 重定?
set args 清理命o行参?/p>
gdb –pid= pid
attach pid
detach pid 分离q程l箋q行
.
quit q程退?/p>
.
q
ctrl
+D
断点
break 普?
tbreak 一ơ?
rbreak 正则表达式一Ҏ?
linespec
标号
explicit
-line number
实践
file banner
b main 中断在main函数
info funciton useage 昄useage函数地址
info *0x88888e4 直接写地址讑֮断点
info b 昄所有断?
list usage 昄useage函数
b line.c:11
b +2 当前昄?4行+2行所以设定在17?/p>
虚拟定硬件断点会p|.
(gdb)hbreak hd_ioctl
(gdb) info b
物理机可以设?
(gdb) hbreak v
Hardware assisted breakpoint 2 at 0x40053a: v. (2 locations)
(gdb) info b
Num Type Disp Enb Address What
1 breakpoint keep y
breakpoint already hit 1 time
1.1 y 0x000000000040054f in main at a.c:10 inf 1
1.2 y 0x000000000040054f in main at a.c:10 inf 2
2 hw breakpoint keep y
2.1 y 0x000000000040053a in v at a.c:4 inf 1
2.2 y 0x000000000040053a in v at a.c:4 inf 2
(gdb)
info b 昄断点
delete 1 删除
disable 1
enable 1
delete 删除所有的断点
clear sum 删除sum函数入口的所有断?/p>
watchpoint 监视一个表辑ּQ值变化中断?/p>
watch aQbQcQd
watch *( int * )
watch fd 监控局部变量fd
c l箋q行
info b //
注意Qx86g调试Q写操作Q执行过q一行,gdb昄下一行,要看上一行。hw watchpointQ在x86q_wachtpointZg实现Q其他^台可能是Z软g实现?vc6UY件执行,执行目标速度低?br/>
执行位置过当前区域Q无效监视点会被删除?/p>
讉K监视?br/>
rwatch d下来?
awatch L写停下来?awatch fd
watch -l
b hd_ioctl thread 1
info threads 带* 当前U程
J忙函数解决Ҏ
b hd_ioctl thread 1 if fd > 0
当断点,断了后执行命?br/>
()command 12
()silent
()print “fd is %d\n”,fd
()continue
()end
动态ping不修改代码?/p>
tracepoint q程L通讯调试Q前端stub立刻恢复执行Q但会记录下来?/p>
catchpoint
q入子函数内部。单?step
汇编 stepi
stepi 4
cMnexti
不要q入子函?
next
l箋执行
continue
跑v来直?h点命?/p>
until 3
跑v来直?h点命中,快捷止其他断点?/p>
恢复执行直到函数q回?/p>
finish
gdb 杜撰代码调用函数?br/> call sumQ?Q?Q?…
强制main函数 return?br/> return 1
异常或断点进入调试器?br/> 调试器发起中断,让程序中断下来。ctrlQCQapp收到中断信号Q进入调试器?/p>
调试器读?调试W号?/p>
二进Ӟ调试W号Q源?/p>
linux dwarf 存储调试W号信息。gcc
readelf -h filename
里面如果有line location debug标示readelf -w 导出调试文g
gcc -g 才能输出W号
ubuntu W号服务?
< ddebs.ubuntu.com/pool/main/>
分离操作
strip
安装ubunte的linux 内核W号
https://askubuntu.com/questions/197016/how-to-install-a-package-that-contains-ubuntu-kernel-debug-symbols
安装libcW号
dpkg -s /lib/x86_64-linux-gun/libc-2.15.so
dpkg -s libc.so.6
sudo apt-get -c aptproxy.conf install libc6-dbg
libc 调试W号
sudo apt-get install libc6-dbg
W号路径
gdb 使用file ?symbolQfile 加蝲W号文g
自动搜烦 path 路径
QgdbQi share
* ׃n库没调试信息
搜烦W号
info vaiables regex cdQ函数名Q变量名
info addriess 函数?/p>
info symbol 地址
(gdb) info address main
Symbol “main” is a function at address 0x400547.
(gdb) info symbol 0x400547
main in section .text of /home/gao/code/a
.
info os
查看加蝲的文件内存位|?/p>
info files
列出全局变量
info variable
info va
list
list -
dir 源码路径
show dir
常用命o源码
安装pȝ工具源码和调?/p>
apt-get source coreutils
sudo apt-get install coreutils-dbgsym
gdb /bin/ls
list main
dir ~/src/coreutils-7.4/src
list main
libc
sudo apt-get source libc6-dev
/home/ge/eglibc-2.15
dir 搜烦路径 Q分?br/>
$cdir ~译路径
cwd 当前工作路径
观察寄存?br/> info reg
?br/>
子函数返回地址
函数参数
局部变?/p>
bt n 观察函数q回地址
frame n 切换栈
up n
down n
info frame QaddressQ?br/> info args
info locals
注意Q切换栈帧之后可能会发生Q本地变量g准确Q因为值存在寄存器中需要小心?/p>
观察内存
print
p /f 表达? 表达式要打印位置
xduotcf
x
x /Nuf
N 打印几个单元
u 每个单元大小 b-1byte w-2byte h-4byte g-8byte
f s字符串i指o格式
x/s 0xfffff81946000 打印字符?/p>
x /32bx arg bit 16制
(gdb) x /32bx &i
0x7fffffffc76c: 0x01 0x00 0x00 0x00 0x70 0x05 0x40 0x00
0x7fffffffc774: 0x00 0x00 0x00 0x00 0x40 0xfa 0xa2 0xf7
0x7fffffffc77c: 0xff 0x7f 0x00 0x00 0x58 0xc8 0xff 0xff
0x7fffffffc784: 0xff 0x7f 0x00 0x00 0x58 0xc8 0xff 0xff
(gdb)p arg[0]
p arg[i]
p *&a[0]@10 a0数组开始的10个元?/p>
反汇~?/p>
disas main main反汇~代?br/> x/5i schedule q个地址开始的5条汇~指令?/p>
gdb mov 从左往双值at&t汇编?/p>
stop 要不要中断下来看
printf 打印信息
pass 要不要传递给应用E序?/p>
handle SIGPIPE 不要中断下来Q打C个信息,|络E序常用
(gdb) handle SIGPIPE nostop
Signal Stop Print Pass to program Description
SIGPIPE No Yes Yes Broken pipe
info threads
LWPQlight weight process U程~号?br/> * gdb当前U程
切换当前U程
thread 2
打印所有线E?/p>
thread apply all bt 针对一线E的命o避免切换来看?/p>
U程改名?/p>
thread name QnameQ?/p>
我自q?LWP 可以很好的观察线E负载情c?/p>
参考资料:
Object-oriented Programming with ANSI-C
1993q_W一份c如何~写OO的资?free.
OOC.PDF
https://www.cs.rit.edu/~ats/books/ooc.pdf
中文译Q?br/> https://code.google.com/p/ooc/downloads/detail?name=ooc-translate-preview-r26.pdf&can=2&q=
轻量U的C语言面向对象~程框架
http://sinojelly.blog.51cto.com/479153/281184
UML—OOPC嵌入式C语言开发精?br/>
里面有一套框架可?c写OO.
http://pan.baidu.com/share/link?shareid=3402978666&uk=3188261067&adapt=pc&fr=ftw#path=%252FC%25E8%25AF%25AD%25E8%25A8%2580
你试q这样写CE序?Q-函数式编E?br/> < >
我所偏爱?C 语言面向对象~程范式Q-云风
http://blog.codingnow.com/2010/03/object_oriented_programming_in_c.html
C语言面向对象~程 -- 6专?br/> http://blog.csdn.net/column/details/object-orient-c.html
** valgrind --tool=cachegrind ./test2**
#include <stdio.h>
#define MAXROW 8000
#define MAXCOL 8000
int main () {
int i,j;
static int x[MAXROW][MAXCOL];
printf ("Starting!\n");
for (i=0;i<MAXROW;i++)
for (j=0;j<MAXCOL;j++)
x[i][j] = i*j;
printf("Completed!\n");
return 0;
}
#include <stdio.h>
#define MAXROW 8000
#define MAXCOL 8000
int main () {
int i,j;
static int x[MAXROW][MAXCOL];
printf ("Starting!\n");
for (j=0;j<MAXCOL;j++)
for (i=0;i<MAXROW;i++)
x[i][j] = i*j;
printf("Completed!\n");
return 0;
}
```
##l果
Command: ./test1
Starting!
Completed!
I refs: 905,721,688
I1 misses: 4,177
LLi misses: 2,808
I1 miss rate: 0.00%
LLi miss rate: 0.00%
D refs: 514,830,867 (386,118,735 rd + 128,712,132 wr)
D1 misses: 4,025,828 ( 23,565 rd + 4,002,263 wr)
LLd misses: 4,008,456 ( 6,997 rd + 4,001,459 wr)
D1 miss rate: 0.8% ( 0.0% + 3.1% )
LLd miss rate: 0.8% ( 0.0% + 3.1% )
LL refs: 4,030,005 ( 27,742 rd + 4,002,263 wr)
LL misses: 4,011,264 ( 9,805 rd + 4,001,459 wr)
LL miss rate: 0.3% ( 0.0% + 3.1% )
gcc -o test2 test2.c
** valgrind --tool=cachegrind ./test2**
I refs: 905,720,801
I1 misses: 4,113
LLi misses: 2,811
I1 miss rate: 0.00%
LLi miss rate: 0.00%
D refs: 514,830,348 (386,118,427 rd + 128,711,921 wr)
D1 misses: 64,025,705 ( 23,462 rd + 64,002,243 wr)
LLd misses: 4,016,427 ( 6,977 rd + 4,009,450 wr)
D1 miss rate: 12.4% ( 0.0% + 49.7% )
LLd miss rate: 0.8% ( 0.0% + 3.1% )
LL refs: 64,029,818 ( 27,575 rd + 64,002,243 wr)
LL misses: 4,019,238 ( 9,788 rd + 4,009,450 wr)
LL miss rate: 0.3% ( 0.0% + 3.1% )
Starting!
Completed!
```
valgrind调试CPU~存命中率和内存泄漏
http://laoxu.blog.51cto.com/4120547/1395236