13-监视工具
22.7 监视工具
在Linux系统中,strace是一种相当有效的跟踪工具,它的主要特点是可以被用来监视系统调用。我们不仅可以用strace调试一个新开始的程序,也可以调试一个已经在运行的程序(这意味着把strace绑定到一个已有的PID上)。对于第6章的globalmem字符设备文件,以strace方式运行如代码清单22.9所示的用户空间应用程序globalmem_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系统调用,其格式为“左边=右边”,等号左边是系统调用的函数名及其参数,右边是该调用的返回值。
代码清单22.9 用户空间应用程序globalmem_test
1 #include ...
2
3 #define MEM_CLEAR 0x1
4 main()
5 {
6 int fd, num, pos;
7 char wr_ch[200] = "This is a test of globalmem";
8 char rd_ch[200];
9 / 打开/dev/globalmem /
10 fd = open("/dev/globalmem", O_RDWR, S_IRUSR | S_IWUSR);
11 if (fd != -1 ) { / 清除globalmem /
12 if(ioctl(fd, MEM_CLEAR, 0) < 0)
13 printf("ioctl command failed\n");
14 / 读globalmem /
15 num = read(fd, rd_ch, 200);
16 printf("%d bytes read from globalmem\n",num);
17
18 / 写globalmem /
19 num = write(fd, wr_ch, strlen(wr_ch));
20 printf("%d bytes written into globalmem\n",num);
21 ...
22 close(fd);
23 }
24 }
使用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()的运行结果。
LDD6410开发板的文件系统中已经包含了strace工具,可以直接使用,对应strace的源代码位于LDD6410工程的utils/strace-4.5.16目录。