我该如何使用strace来嗅探串口?

时间:2013-11-11 22:14:46

标签: c linux serialization sniffing strace

我正在linux中编写应用程序,需要访问串口。 出于调试目的,我需要查看来自和/或通过串口的内容。

我环顾四周,发现我可以用strace来做到这一点。所以我尝试了以下内容:

-I打印我使用的串行设备的file_descriptor。

(重启我的应用程序几次后,我向自己保证,我的应用程序从内核获取的file_descriptor编号是“4”

- 如果我以strace -e write=4 ./myapp启动我的应用程序,我希望只能从file_descriptor“4”获取终端中的消息。相反,我得到了输出:

read(5, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0(\0\1\0\0\0\300Q\254C4\0\0\0"..., 52
fstat64(5, {st_mode=S_IFREG|0644, st_size=1448930, ...}) = 0                    
mmap2(0x43ab8000, 153816, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 5, 0)0
mprotect(0x43ad6000, 28672, PROT_NONE)  = 0                                     
mmap2(0x43add000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRI0
close(5)                                = 0                                     
munmap(0x2ab4c000, 38409)               = 0                                     
exit(0)   

来自几个不同的file_descriptors。

如果我使用strace -e trace=write -e write=4 ./myapp

运行我的应用

我会得到更少的消息,即使它们仍然很多,或者file_descriptor“1”。

write(1, "GPIO data bank:0x8, data: 0x80 a"..., 52GPIO data bank:0x8, data: 0x81) = 52                                                                          
write(1, "\n", 1)   = 1                                                     
write(1, "--> Version: 0677 <--\n", 22--> Version: 0677 <-- ) = 22                                                                          
serial fd = 4 

您在上面看到的是一些printf语句。 非常奇怪的部分是行serial fd = 4也是一个printf语句,但由于某种原因,它不包含write(fd, ....)输出中的strace语句。 也有人可以解释一下吗?

谢谢你的帮助。

1 个答案:

答案 0 :(得分:4)

尝试一下简单。

strace -e write=1 echo foo

这将写入所有系统调用,除此之外,写入fd 1的数据。

strace -e trace=none -e write=1 echo foo

除了程序本身的输出外,这不会产生任何输出。如果您想查看其数据,似乎必须跟踪write

strace -e trace=write -e write=1 echo foo

这将打印所有写入系统调用,用于任何文件描述符。除此之外,它将打印发送到描述符1的数据的转储。输出将如下所示:

write(1, "foo\n", 4foo
)                    = 4
 | 00000  66 6f 6f 0a                                       foo.             |
+++ exited with 0 +++

系统调用从第一行开始。在参数列表之后,实际执行了系统调用,并打印foo后跟换行符。然后通过strace打印系统调用返回值。之后,我们有了数据转储。

我建议使用-e trace=write -e write=4 -o write4.txt后跟grep '^ |' write4.txt或类似的东西。如果您想实时查看数据,可以使用这样的bash重定向:

strace -e trace=write -e write=4 -o >(grep '^ |') ./myapp

这会将strace的输出发送到grep,您可以在其中删除write系统调用并专注于数据转储。

  

非常奇怪的部分是,行serial fd = 4也是一个printf语句,但由于某种原因它并没有包含在write(fd, ....)输出中的strace语句中。也有人可以解释一下吗?

我会说这行不是来自strace,而是来自某些应用程序。这就是它没有被包裹的原因。事实上,除了那个未被打开的文本之外,没有包装版本(如我上面的foo示例输出中所示),表明输出可能源自myapp所包含的子进程。也许您想添加-f,以便您遵循子流程创建?

请注意,孩子可能决定重命名其文件描述符,例如将其标准输出重定向到父级打开的串行端口。如果发生这种情况,write=4将不再合适。为了安全起见,我将整个-f -e trace=write输出写入文件,并查看它以查看数据实际写入的位置。然后根据数据调整内容。