SA19225291 倪嘉瑞 作业二

一、实验要求

  • 在VSCode下编译运行lab5-1.tar.gz 

  • 通过VSCode+GDB调试程序找出quit命令无法运行的bug产生的原因

  • 分析callback接口的运行机制,总结callback接口设计的方法

二、实验过程

     (一)在VSCode下编译运行lab5-1.tar.gz 

      linktable.h中包含了pthread.h,该头文件在windows环境下无法编译通过,因此需要下载 

 

 

  将以下三个头文件放到mingw目录下的include中去

    再将以下文件放入mingw目录下的lib中

   

   可以看到pthread.h的导入不再报错,进行编译,编译命令如下

        

   编译过程报错

       

  这里是说结构体被重复定义了,因此找出pthread.h和time.h文件查看,果然两个头文件中都对timespec这个名称进行了结构体的定义

  那么我们在#include 之前定义

   来告诉该头文件我们有了正确的名为timespec的结构体,这样代码便可以正确的编译。

  但是程序仍然报错

      SA19225291 倪嘉瑞 作业二_第1张图片

      检查发现我们在windows下使用pthread.h时需要在编译命令后加上-lpthread

  最终命令如下

     对应目录下成功生成exe文件

     

   但是执行之后又报错如下

    SA19225291 倪嘉瑞 作业二_第2张图片

    那么我们根据提示将对应的dll文件添加到当前目录下

SA19225291 倪嘉瑞 作业二_第3张图片

    运行成功

    

    至此编译运行过程结束。

 

 (二)通过VSCode+GDB调试程序找出quit命令无法运行的bug产生的原因

  首先来看初始化链表的函数

        

   SA19225291 倪嘉瑞 作业二_第4张图片

  从这段代码中可知,该函数创建了一个链表,其中有三个节点,第一个节点叫help,第二个节点叫version,第三个节点叫quit,并且定义了头节点和尾节点。

  显然quit位于链表末尾。

  接下来我们继续看主函数

       

  这里有一个匹配输入和链表的函数。那么考虑到quit字符未被正确识别的原因就在这个函数里,因此从此处开始使用gdb进行调试。

  由于之前编译时没有添加-g,因此无法直接调试,需要重新进行编译。编译命令如下:

  

  在命令行中输入gbd test进行调试。

  

   在该函数处打下断点,即109行。

        

  运行程序

     SA19225291 倪嘉瑞 作业二_第5张图片

   这里程序停止在了断点处,可见是一个函数,输入s进入函数内。

       

   可以看到gdb调试过程中可以显示出参数传递的具体值,这里quit成功传参。

  使用s继续进入下一个函数。

  

   使用n逐行执行函数。

  SA19225291 倪嘉瑞 作业二_第6张图片

   这里可以看到while执行了两次,然后第三次没有满足循环条件,那么结合代码问题就很明显了。

  该循环执行到链表的末尾节点的时候,因为没满足循环条件从而结束了循环,也就是说quit节点没有被读到也就没有与用户输入进行匹配。

  那么为了while循环能够正确的读到quit节点,将while条件修改如下:

  

   重新编译并执行代码

  

   执行正确。

 

 (三)分析callback接口的运行机制,总结callback接口设计的方法

   这里使用到了callback机制

     SA19225291 倪嘉瑞 作业二_第7张图片

      回调函数是把函数的指针作为参数传递给另一个函数,callback函数的调用实质上是在一个模块内部调用模块外部的另一个模块实现的函数。这种方式提供了极大的灵活性。

   那么如何设计回调函数?

    1、先定义回调函数原型,顺便定义一个新的指针变量类型。
    2、设计者以该回调函数指针变量类型定义新的变量,实现参数传递和数据保存。
    3、调用前先检查指针有效性,避免跳到空指针处,造成崩溃。

 

你可能感兴趣的:(SA19225291 倪嘉瑞 作业二)