问题描述
我正在用linux编写应用程序,需要访问串行端口.出于调试目的,我需要截取串行端口来回的信息.
I am writing an application in linux and need to access the serial port.For debugging purposes I need to snif what comes and/or goes through the serial port.
我环顾四周,发现可以使用strace做到这一点.所以我尝试了以下方法:
I looked around and found out I can use strace to do that. So I tried the following:
-我打印出我使用的串行设备的file_descriptor.
-I print the file_descriptor of the serial device that I use.
(重新启动应用程序几次后,我向自己保证,我的应用程序从内核获取的file_descriptor号为"4"
(after restarting my application a few times, I reassured myself that the file_descriptor number my application gets from kernel is "4"
-如果我以strace -e write=4 ./myapp
的身份启动我的应用程序,则希望在终端中仅从file_descriptor"4"获取消息.相反,我得到了很多输出:
-if i start my application as strace -e write=4 ./myapp
, I would expect to get messages in the terminal, from file_descriptor "4" only. instead I get looots of output:
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_descriptor.
from several different file_descriptors.
如果我使用strace -e trace=write -e write=4 ./myapp
即使它们仍然很多,和/或file_descriptor"1",我得到的消息也要少得多.
I'll get far less message, even though they will still be many, and or 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语句,但是由于某些原因,它没有被strace
输出中的write(fd, ....)
语句包裹.有人也可以解释吗?
what you see above are some printf
statements.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 -e write=1 echo foo
这将写入所有syscall,此外,还将写入fd 1的数据.
This will write all syscalls, and in addition to these, the data written to fd 1.
strace -e trace=none -e write=1 echo foo
除了程序本身的输出外,不会产生任何输出.如果要查看其数据,似乎必须跟踪write
.
This will generate no output except for the output from the program itself. It seems you have to trace write
if you want to see its data.
strace -e trace=write -e write=1 echo foo
这将打印任何文件描述符的所有写syscall.除此之外,它将打印发送到描述符1的数据的转储.输出将如下所示:
This will print all write syscalls, for any file descriptor. In addition to that, it will print a dump of the data sent to descriptor 1. The output will look like this:
write(1, "foo\n", 4foo
) = 4
| 00000 66 6f 6f 0a foo. |
+++ exited with 0 +++
系统调用从第一行开始.在参数列表之后,实际上会执行syscall,并显示foo
和换行符.然后,由strace打印syscall返回值.之后,我们进行了数据转储.
The syscall starts in the first line. After the list of arguments, the syscall is actually executed, and prints foo
followed by a newline. Then the syscall return value is printed by strace. After that, we have the data dump.
我建议先使用-e trace=write -e write=4 -o write4.txt
,再使用grep '^ |' write4.txt
或类似的名称.如果要实时查看数据,可以使用bash重定向,如下所示:
I'd suggest using -e trace=write -e write=4 -o write4.txt
followed by grep '^ |' write4.txt
or something like that. If you want to see data in real time, you can use a bash redirection like this:
strace -e trace=write -e write=4 -o >(grep '^ |') ./myapp
这会将输出从strace发送到grep,您可以在其中剥离write
syscalls并专注于数据转储.
This will send output from strace to grep, where you can strip the write
syscalls and concentrate on the data dumps.
我会说那行不是从strace输出,而是从某些应用程序输出.这就是它没有被包裹的原因.除已包装版本外,没有包装版本出现(例如,在上述我的foo
示例输出中),这一事实表明该输出可能源自myapp
所属的子进程.也许您想添加-f
以便跟随子进程的创建?
I'd say that line is output not from strace, but from some application. That's the reason it is not wrapped. The fact that no wrapped version of this appears in addition to that unwrapped one (like in my foo
example output above) suggests that the output might originate in a child process lainced by myapp
. Perhaps you want to add -f
so you follow child process creation?
请注意,孩子可能决定重命名其文件描述符,例如将其标准输出重定向到父级打开的那个串行端口.如果发生这种情况,write=4
将不再适用.为了安全起见,我将整个-f -e trace=write
输出写入文件,然后查看该文件以查看实际写入数据的位置.然后调整内容,以将其置入该数据中.
Notice that a child might decide to rename its file descriptors, e.g. redirect its standard output to that serial port opened by the parent. If that happens, write=4
won't be appropriate any more. To be on the safe side, I'd write the whole -f -e trace=write
output to a file, and look at that to see where the data actually gets written. Then adjust things to home in on that data.
这篇关于我应该如何使用strace来监听串行端口?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!