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

标签 c linux serialization sniffing strace

我正在用linux写一个应用程序,需要访问串口。 出于调试目的,我需要嗅探通过串口传入和/或传出的内容。

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

-我打印我使用的串口设备的文件描述符。

(重启我的应用程序几次后,我向自己保证我的应用程序从内核获取的 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)   

来自几个不同的文件描述符。

如果我使用 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 输出中的语句。 有人也可以解释一下吗?

谢谢你的帮助。

最佳答案

尝试一些简单的东西。

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 后跟换行符。然后 syscall 返回值由 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 系统调用并专注于数据转储。

The extremely weird part is that the line serial fd = 4 is also a printf statement, but for some reason it is not wrapped around write(fd, ....) statement in strace output. Can someone explain that, too?

我会说该行不是从 strace 输出的,而是从某个应用程序输出的。这就是它没有被包裹的原因。除了未包装的版本(如我上面的 foo 示例输出)之外,没有出现此包装版本的事实表明输出可能源自 myapp 的子进程>。也许您想添加 -f 以便跟踪子进程创建?

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

关于c - 我应该如何使用strace来嗅探串口?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19917028/

相关文章:

c - Valgrind 读取大小无效

c - Cygwin 中的 mq_notify 不会触发

linux - 如何在shell脚本中添加缩进

c# - 使用 BinaryFormatter 序列化和反序列化对象图

java - 数据库存储与文件存储

c# - 如何将从 XSD 生成的类序列化为 XML

c - 字符数组的状态

c - 如何在Linux C中读取另一个进程的输出

linux - 为什么在使用 xshell 4.0 时 alt+tab 不起作用?

c - 我收到消息 : Cannot convert 'float' to 'float*' in assignment and i have some logical mistakes