■实验 2.1 GCC_GDB 编译调试工具
一、实验任务
1. 编译运行附录 A 和附录 B 中的程序。
2. 用 GDB 进行调试。调试过程中学习使用附录 C 中的 GDB 命令。
★针对附录 A 中的程序,完成以下任务:
a) 修正附录 A 中的 bug,使程序能够正确运行。
该程序的正确运行结果是依据结构 item 中的 key 值,按照从小到大的顺序,对
数组 array 进行排序,并打印出排序后的结果。
b) 扩展程序功能:程序运行时从命令行传入参数,由参数指定排序方式-顺序或逆序。
二、实验报告
1. GDB 调试过程。GDB 命令使用情况截图。
(挑几个有代表性的命令截图即可,测试目录
为学生姓名)
2. 打印 bug 修正后的源码,并标出修改之处。
3. 打印功能扩展后的程序源码,并标出修改之处。
附录 A:源码 debug.c
typedef struct {
char data[4096];
int key;
} item;
item array[] = {
{"bill", 3},
{"neil", 4},
{"john", 2},
{"rick", 5},
{"alex", 1},
};
sort(a,n)
item *a;
{
int i = 0, j = 0;
int s = 1;
for(; i < n & s != 0; i++) {
s = 0;
for(j = 0; j < n; j++) {
if(a[j].key > a[j+1].key) {
item t = a[j];
a[j] = a[j+1];
a[j+1] = t;
s++;
}
}
n--;
}
}
main()
{
int i;
sort(array,5);
for(i = 0; i < 5; i++)printf("array[%d] = {%s, %d}\n",i, array[i].data,array[i].key);
}
附录 B: 源码 test.c
#include
#include
static int sum(int value);
struct inout{
int value;
int result;
};
int main(int argc, char *argv[])
{
struct inout *io = (struct inout*)malloc(sizeof(struct inout));
/*申请内存*/
if(NULL == io) {
printf("申请内存失败\n");
return -1;
}
if(argc !=2) { /*判断输入参数是否正确*/
printf("参数输入错误!\n");
return -1;
}
io->value = *argv[1]-'0'; /* 获得输入的参数 */
io->result = sum(io->value); /* 对 value 进行累加求和 */
printf("你输入的值为:%d,计算结果为:%d\n",io->value,io->result);
return 0;
}
static int sum(int value){
int result = 0;
int i = 0;
for(i=0;i<=value;i++) /* 循环计算累加值 */
result += i;
return result; /*返回结果*/
}
GDB 命令
编译时需要加上 -g 选项
zhs@zhs-virtual-machine:~/Linux$ gcc -g test.c -o test
编译后得到可执行文件 test ,运行程序
zhs@zhs-virtual-machine:~/Linux$ ./test 3
进入 GDB
$ gdb
$ gdb test
加载文件 file
(gdb) file test
设置输入参数 set args
set args 参数 1 参数 2 …
(gdb) set args 3
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
运行程序 run / r
run args
(gdb) run 3
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
打印代码内容 list / l
List [开始行号, 结束行号]
(gdb) list 1 从第 1 行开始列出代码,每次按 Enter 后顺序向下列出代码
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
设置断点 break / b
break 行号
break 函数名称
break 行号或者函数 if 条件
(gdb) b 21
(gdb) b sum
(gdb) b test.c:21
(gdb) b test.c:sum
(gdb) b 38 if i==2
删除断点 delete breakpoints Num
(gdb) delete breakpoints 1
5
禁止断点 disable
(gdb) disable b 2
允许断点 enable
(gdb) enable b 2
清除断点 clear
clear 源码行号
(gdb) clear 29
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
继续运行 cont / c
单步执行下一行 next / n
单步执行,进入函数 step / s
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
显示变量 display
(gdb) display i 每次停止时显示变量 i 的值
打印数据 print / p
(gdb) p i 打印变量的值
(gdb) p 2+3 打印常量表达式的值
(gdb) p sum(3) 计算函数调用的返回值
(gdb) p *io 打印一个结构中各个成员的值
(gdb) p $9 打印历史值
(gdb) p *io@2 打印从 io 开始的两个数据结构
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
变量类型检测 whatis / ptype
whatis 打印变量类型
ptype 打印结构的详细定义
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
显示信息 info
(gdb) info break 显示断点信息
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
调用路径 backtrace / bt
(gdb) backtrace
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
多线程
info thread 列出当前进程中的线程号
6
thread id 进入需要调试的线程
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
汇编 disassemble
disassemble sum 打印指定函数的汇编代码
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
帮助信息 help
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
退出 quit / q
(gdb) quit
修改代码 :
// File Name: debug.c
#include
#include
#include
#include
#include
typedef struct {
char data[4096] ;
int key ;
} item ;
item array[] = {
{"bill",3} ,
{"neil",4} ,
{"john",2},
{"rick",5},
{"alex",1},
};
void sort(item *a , int n , int parm) {
// 修改之后
// 错误一 段错误 : 数组越界
// 错误二 n 的值不能变
//
int i = 0 , j = 0 ;
int s = 1 ;
if(parm == 1 ) { // 从小到大
for(;i a[j+1].key){
item t = a[j] ;
a[j] = a[j+1] ;
a[j+1] = t ;
s++ ;
}
}
// n-- ; 注释掉即可
}
}
else if (parm == 2 ) { // 从大到小
for(;i
// File Name: test.c
// Author: xiaxiaosheng
// Created Time: 2019年08月29日 星期四 09时59分58秒
#include
#include
#include
static int sum(int value ) ;
struct inout{
int value ;
int result ;
};
int main(int argc , char *argv[]){
struct inout *io = (struct inout *) malloc(sizeof(struct inout)) ;
if(!io) {
printf("申请内存失败!\n") ;
return -1 ;
}
if(argc !=2) {
printf("参数输入错误!\n") ;
return -1 ;
}
io->value = *argv[1]-'0' ;
io->result = sum(io->value) ;
printf("你输入的值为 : %d , 计算结果 %d \n" ,io->value , io->result) ; ;
return 0 ;
}
static int sum(int value) {
int result = 0 ;
int i = 0 ;
for(i = 0 ; i<=value ; i++ ) result +=i ;
return result ;
}
zhs@zhs-virtual-machine:~/Linux$ ./debug 1 # 参数1
array[0] = {alex , 1}
array[1] = {john , 2}
array[2] = {bill , 3}
array[3] = {neil , 4}
array[4] = {rick , 5}
zhs@zhs-virtual-machine:~/Linux$ ./debug 2 参数2
array[0] = {rick , 5}
array[1] = {neil , 4}
array[2] = {bill , 3}
array[3] = {john , 2}
array[4] = {alex , 1}