Linux 实验(一)

            第 2 章 GCC_GDB 编译调试工具

实验 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} 

 

你可能感兴趣的:(Linux)