网站建设二公司,美团网站制作的特色,可以做推广的平台,人工智能培训心得体会GDB基本使用
GDB是Linux下一款非常强大的调试软件#xff0c;其实就是GNU Debugger的缩写。接下来我们学习一下他的基本使用。 例子函数#xff0c;其中只有一个ds18b20的采集温度函数和一个主函数#xff1a;
#include stdio.h
#include errno.h
#includ…GDB基本使用
GDB是Linux下一款非常强大的调试软件其实就是GNU Debugger的缩写。接下来我们学习一下他的基本使用。 例子函数其中只有一个ds18b20的采集温度函数和一个主函数
#include stdio.h
#include errno.h
#include string.h
#include sys/types.h
#include dirent.h
#include unistd.h
#include sys/types.h
#include sys/stat.h
#include fcntl.h
#include stdlib.hint measure_temp(float *temp);int main(int argc,char *argv[])
{float temp 0;measure_temp(temp);printf(the temp:%f\n,temp);return 0;
}int measure_temp(float *temp)
{int fd -1;//打开ds18b20时候的文件描述符int found -1;//是否找到chip的参数。char *w1_path /sys/bus/w1/devices/; //文件名的前半段,28-后面不能确定因为设备号会变化我们一会获取。char chip[32];//文件名的后半段-28char ds_path[128];//拼凑出全部的路径名DIR *dirp NULL;//打开w1时返回的DIR类型文件指针struct dirent *direntp NULL;//是readdir后返回的文件夹信息结构体指针char buf[1024];char *ptr;//用来指向温度值if (NULL temp){printf(mesure_temp arguments error:[%s]\n,strerror(errno));return -1;}printf(measure_temp arguments right!\n);//打开devices文件夹if ( NULL (dirp opendir(w1_path)) ){printf(open w1_path error:[%s]\n,strerror(errno));return -2;}printf(open w1_path DIR[%p] success!\n,dirp);//readdir查找这个文件夹下有什么while(NULL ! (direntpreaddir(dirp))){if (strstr(direntp-d_name,28-)){strncpy(chip,direntp-d_name,sizeof(chip));//duancuowufound 1;}}closedir(dirp);if (found 0){printf(nofind \-28\ \n);return -3;}printf(find chip success[%s]\n,chip);snprintf(ds_path,sizeof(ds_path),%s%s/w1_slave,w1_path,chip);printf(ds_path:%s\n,ds_path);if ((fd open(ds_path,O_RDONLY)) 0){printf(open error[%s]\n,strerror(errno));return -4;}int i;int *p NULL;p i;//read fd memset(buf,0,sizeof(buf));if ( read(fd,buf,sizeof(buf)) 0 ){printf(error:[%s]\n,strerror(errno));return -5;}//printf(temperature:[%s]\n,buf);if ( NULL (ptr strstr(buf,t) )){printf(nofound error[%s]\n,strerror(errno));return -6;}//printf(%s\n,ptr);ptr 2;*temp atof(ptr)/1000;return 0;
}
1首先我们使用 gcc 直接生成的程序是没有调试信息的所以我们要使用 gcc -g 命令来生成一个带有调试信息版本的目标文件。 2然后我们用 gdb 来打开这个目标文件其实就是让带有调试信息的二进制文件在我们 gdb 的这个 “盒子” 里面进行运行。 用 gdb 目标文件 命令来运行它。 3之后我们就可以开始调试啦如何让 test_gdb.o 这个文件在gdb中跑起来呢在 gdb 中输入 run 就可以了。 4不过我们发现这和不使用 gdb 跑程序没有什么区别所以我们学习如何增加断点。
增加断点是通过 break 命令来实现的他有三种基本的使用形式如下
(gdb) break main # 在 main 函数处设置断点
(gdb) break my_program.c:10 # 在 my_program.c 文件的第 10 行设置断点
(gdb) break my_function # 在 my_function 函数处设置断点5这里假设我们程序异常退出了但我们不清楚导致退出的错误是发生在 measure 测温函数内还是函数之前我们就可以在进入这个函数之前设置一个断点然后运行它。 我们可以看到程序成功运行到了这个函数前没有抛出异常那么我们就可以确定异常是在 measure 测温函数内的了。
6使用 next 单步执行但是不进入到函数内部。 7也可以使用step单步执行但是会进入到函数内部。 8使用bt命令或者backtrace命令显示调用的栈信息 9显示所有的断点 10删除特定的某一个断点 运行到某一个断点后要直接运行到下一个断点使用continue 或者 c 就可以了。若后面没有断点了那么就会一直运行到结束或者某个循环里面。
命令汇总
(gdb) break main # 在 main 函数处设置断点
(gdb) break my_program.c:10 # 在 my_program.c 文件的第 10 行设置断点
(gdb) break my_function # 在 my_function 函数处设置断点(gdb) next # 或 (gdb) n 单步执行不进入函数内部
(gdb) step # 或 (gdb) s 单步执行进入函数内部
(gdb) finish # 运行到当前函数返回的位置
(gdb) until # 运行到循环结束的位置(gdb) run # 启动程序
(gdb) continue # 或 (gdb) c 继续运行直到下一个断点(gdb) backtrace # 或 (gdb) bt 显示调用栈
(gdb) frame n # 切换到调用栈中的第 n 帧
(gdb) info frame # 显示当前帧的信息
(gdb) info locals # 显示当前帧的局部变量(gdb) info breakpoints # 或 (gdb) info b 显示所有断点
(gdb) delete breakpoint_number # 或 (gdb) d breakpoint_number 删除特定断点
(gdb) clear # 删除当前行的断点
(gdb) disable breakpoint_number# 禁用特定断点
(gdb) enable breakpoint_number # 启用特定断点当然我们也可以在运行过程中对某些变量进行查看和修改
这里用到的命令是
print 变量名 #打印变量的值注意没有print没有f。
set var 变量 值 # 改变某个变量的值