第21章 Linux设备驱动的调试之strace

21.8 strace

    在Linux系统中,strace是一种相当有效的跟踪工具,strace的主要特点是可以被用来监视系统调用。不仅可以用strace调试一个新开始的程序,也可以调试一个已经在运行的程序(这意味着把strace绑定到一个已有的PID上)。对于第6章的globalmem字符设备文件,以strace方式运行如代码清单21.8所示的用户空间应用程序globalmem_test(使用gcc命令编译globalmem_test.c文件 gcc globalmem_test.c -o test),以strace ./test的方式运行结果如下:

execve("./globalmem_test", ["./globalmem_test"], [/* 24 vars */]) = 0
...
open("/dev/globalmem", O_RDWR)        = 3   /* 打开的/dev/globalmem的fd是3 */
ioctl(3, FIBMAP, 0)                  = 0

read(3, 0xbff17920, 200)           = -1 ENXIO (No such device or address)/* 读取失败 */
fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7f04000
write(1, "-1 bytes read from globalmem\n", 29-1 bytes read from globalmem
) = 29                           /* 向标准输出设备(fd为1)写入printf中的字符串 */
write(3, "This is a test of globalmem", 27) = 27
write(1, "27 bytes written into globalmem\n", 3227 bytes written into globalmem
) = 32
...

     输出的每一行对应一次Linux系统调用,其格式为“左边=右边”,等号左边是系统调用的函数名及其参数,右边是该调用的返回值。

代码清单21.8 用户空间应用程序globalmem_test

 #include ...
 
 #define MEM_CLEAR 0x1
 void main(void)
 {
          int fd, num, pos;
          char wr_ch[200] = "This is a test of globalmem";
          char rd_ch[200];
          /* 打开/dev/globalmem */
          fd = open("/dev/globalmem", O_RDWR, S_IRUSR | S_IWUSR);
          if (fd != -1 ) { /* 清除globalmem */
                 if(ioctl(fd, MEM_CLEAR, 0) < 0)
                      printf("ioctl command failed\n");
             /* 读globalmem */
             num = read(fd, rd_ch, 200);
             printf("%d bytes read from globalmem\n",num);

           / * 写globalmem */
           num = write(fd, wr_ch, strlen(wr_ch));
           printf("%d bytes written into globalmem\n",num);
           ...
           close(fd);
         }
}

    使用strace虽然无法直接追踪到设备驱动中的函数,但是足以帮助工程师进行推演:

如从open(“/dev/globalmem”,O_RDWR)=3的返回结果知道/dev/globalmem的fd为3,之后对fd为3的文件进行read()、write()和ioctl()系统调用,最终会使globalmem里file_operations中的相应函数被调用,通过系统调用的结果就可以知道驱动中globalmem_read()、globalmem_write()和globalmem_ioctl()的运行结果。



你可能感兴趣的:(Linux驱动开发)