20155320 信息安全系统设计第二周课堂考试总结及myod的实现

第二周测试一二已在课上提交

第二周测试3-gdb测试

  1. 用gcc -g编译vi输入的代码
  2. 在main函数中设置一个行断点
  3. 在main函数增加一个空循环,循环次数为自己学号后4位,设置一个约为学号一半的条件断点
  4. 提交调试过程截图(一定包含条件断点的),要全屏,包含自己的学号信息

首先我再次巩固了一遍cgdb调试的知识。

  • b 设断点(要会设4种断点:行断点、函数断点、条件断点、临时断点)
  • run 开始运行程序
  • bt 打印函数调用堆栈
  • p 查看变量值
  • c 从当前断点继续运行到下一个断点
  • n 单步运行
  • s 单步运行
  • quit 退出CGDB
  • 四种断点的设法

1.条件断点:b fxx(函数名)

2.条件断点:b 12 if i=5000

  1. 行断点:b 行号

4.临时断点:tb 行号

所以我输入了b 13 if i==2660 设置了条件断点循环次数为学号的一半

码云代码

截图如下:

20155320信息安全系统设计第二周课堂考试总结及myod的实现-LMLPHP

第二周测试4-静态库的测试

  1. 除了main.c外,其他4个模块(add.c sub.c mul.c div.c)的源代码不想给别人,如何制作一个mymath.a静态库?main.c如何使用mymath.a?

  2. 提交静态库生成和调用过程截图(一定包含条件断点的),要全屏,包含自己的学号信息

首先通过博客linux下制作静态库和动态库的方法

学习了一下静态库的设计方法:

1.把代码编译为目标文件形式(形如):

gcc -c liberr.c -o liberr.o

2.使用工具ar创建一个存档文件:

ar rcs mymath5320.a sub5320.o add5320.o mul.o div.o

3.编译程序时把程序和mymath.a链接起来:

gcc -static -o link5320 main.o mymath.a

4.运行link5320

./link5320

截图如下:

20155320信息安全系统设计第二周课堂考试总结及myod的实现-LMLPHP

第二周测试5-共享库

  1. 除了main.c外,其他4个模块(add.c sub.c mul.c div.c)的源代码不想给别人,如何制作一个mymath.so共享库? main.c如何使用mymath.so?

  2. 提交共享库生成和调用过程截图(一定包含条件断点的),要全屏,包含自己的学号信息

步骤如下:

1.创建一个共享目标文件

gcc -shared -fpic -o mymath.so add5320.c sub5320.c mul.c div.c

2.创建可执行目标文件

gcc -o link main.c ./mymath.so

3.运行link

./link

截图如下:

20155320信息安全系统设计第二周课堂考试总结及myod的实现-LMLPHP

第二周测试6-Makefile(已在蓝墨云上提交)

1 写出编译上面vi编辑代码的makefile,编译出来的目标文件为testmymath, 只用显式规则就可以.

2 提交Make过程截图,要全屏,包含自己的学号信息

首先我找了个博客教程Linux下GCC和Makefile实例(从GCC的编译到Makefile的引入)

截图如下:

20155320信息安全系统设计第二周课堂考试总结及myod的实现-LMLPHP

myod

1 复习c文件处理内容

2 编写myod.c 用myod XXX实现Linux下od -tx -tc XXX的功能

  1. main与其他分开,制作静态库和动态库

  2. 编写Makefile

5 提交测试代码和运行结果截图, 提交调试过程截图,要全屏,包含自己的学号信息

6 在博客园发表一篇博客,重点写遇到的问题和解决过程

代码码云链接

head.h

#ifndef HEAD_H
#define HEAD_H
void od(char STR[],int);
#endif

myod.c

主要实现读取和关闭文件

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
//char filepath[100]; FILE *fp;
fp=fopen("test.txt","rb");
if(fp==NULL){
printf("Failure to open file\n");
return 0;
}
char ch;
char STR[1000];
int i,n;
i=0;
while((ch=fgetc(fp))!=EOF){
STR[i]=ch;
i++;
//putchar(ch);
}
STR[i]='\0';
//printf("%d",i);
fclose(fp);
od(STR,i);
}

od.c

用于实现文件中字符逐个输出以及od -tx -tc 的功能

#include"head.h"
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void od(char STR[1000],int i)
{
int k=1;
int j=0;
int m=0;
int line=0;
printf("%06d ",line);
putchar(STR[0]);
for(k=1;k<=i;k++){
if(k%16!=0&&STR[k]!='\0'){
if(STR[k]!='\n')
{
printf(" %2c",STR[k]);
continue;
}
else{
printf(" \\n");
continue;
}
}
else{
printf("\n ");
for(j=m;j<k;j++){
printf(" %02x",STR[j]);
}
printf("\n%06d",k+2); m=k;
}
}
printf("\n");
}

PS:题目隐含的要求

编程中遇到的问题

问题1:编程完毕运行时出现如下图的结果:

20155320信息安全系统设计第二周课堂考试总结及myod的实现-LMLPHP

解决方法:我先取消myod.c中对od.c的调用,在myod.c中输出字符,输出文件正常,发现问题出现在od.c中,再在od.c中用cgdb调试,发现是在逐个输出字符的循环中有问题,解决完后能正常输出字符,但出现了问题2。

问题2:运行结果如下图:

20155320信息安全系统设计第二周课堂考试总结及myod的实现-LMLPHP

解决办法:单步调试时,发现了以下几个地方出现了问题

修改前如下:

for(k=0;k<i;k++){
if(k%16!=0&&STR[k]!='\0'){
  • 在循环中k不能从0开始计数,因为这样k%16一开始就等于0了,所以k应该从1开始

  • 由于我STR[]是将整个文件存储成一个字符串,共i个字符,而实际上当k=i时,已经不能进入循环了,这就无法满足i<16也需换行输出ASCII码值的情况,所以k应1<=i,且为使

    '\0'成为文件中字符输出结束的标志,我在myod.c中

STR[i]='\0';

问题3:解决完问题2之后,输出显示如下图:

20155320信息安全系统设计第二周课堂考试总结及myod的实现-LMLPHP

解决:通过比较我才发现了第三个隐含条件,每行前输出的不是行号而是字符统计。我在od.c 中将line++改为k+2,在输出完ASCII码后增加了一个换行即达到了效果

for(j=m;j<k;j++){
printf(" %02x",STR[j]);
}
printf("\n%06d",k+2);

最后正确的运行结果截图,包括makefile,动态库、静态库链接如下:

20155320信息安全系统设计第二周课堂考试总结及myod的实现-LMLPHP

总结

这次的考试总体来说都是之前让学习的内容,难度并不大。但是由于对cgdb和链接的掌握不熟练,导致课上测试的时候仍然手忙脚乱。以后的课下学习还需要更加认真,要求实践的内容都要熟练掌握。

同时在这次myod的练习中确实产生了许多麻烦,最开始是文件的读取,当时学c的时候就没学好,这次只好再翻书学了一遍。调试真的很重要,许多问题光看是看不出来的。虽然这次编这个代码耗费了我许多精力,但编完确实感觉受益匪浅。

05-11 13:29