Linux 如何监视进程和终端之间的通信?

Linux 如何监视进程和终端之间的通信?,linux,terminal,embedded-linux,tty,pty,Linux,Terminal,Embedded Linux,Tty,Pty,我有一个由第三方开发的与终端通信的Linux进程。对于调试,我希望看到通信来回进行 人们可能会认为,cat会起作用(看到一个方向): ……但事实并非如此。相反,cat将窃取应用程序所需数据的一半,这几乎毫无价值 第三方应用程序硬编码为假定/dev/tty 我发现监视通信的一种方法是将/dev/tty设备重命名为,比如说,/dev/real\u tty,并在其位置创建一个名为/dev/tty的命名管道。然后运行: cat /dev/real_tty | tee /dev/tty &

我有一个由第三方开发的与终端通信的Linux进程。对于调试,我希望看到通信来回进行

人们可能会认为,
cat
会起作用(看到一个方向):

……但事实并非如此。相反,
cat
将窃取应用程序所需数据的一半,这几乎毫无价值

第三方应用程序硬编码为假定
/dev/tty

我发现监视通信的一种方法是将
/dev/tty
设备重命名为,比如说,
/dev/real\u tty
,并在其位置创建一个名为
/dev/tty
的命名管道。然后运行:

    cat /dev/real_tty | tee /dev/tty &
…通过将数据从
/dev/real\u tty
复制到命名管道
/dev/tty
stdout
,至少让我看到
/dev/real\u tty
的输出

这种方法可以工作,但感觉很不可靠,而且依赖于更换设备的诡计。它也不能在两个方向上工作,因为命名管道只在一个方向上传输数据

正确的方法是什么


如果有人想知道,TTY设备是一个连接到微控制器的RS-232链路。该信息不敏感或不安全。所有进程(应用程序和SPIE)都可以作为root运行。

您考虑过使用吗?您可以看到它正在进行的系统调用,特别是您可以看到正在进行的write/ioctl etc调用。

有一些替代方案:

使用GDB自己动手:

允许您捕获Linux中正在运行的进程的状态并将其保存到文件中。然后,可以使用此文件在重新启动后,甚至在另一台计算机上恢复该过程

是一个透明的工具 检查点任意程序组的状态
跨多台机器并通过插座连接。

?只需用夹子轻触RxD/TxD/GND线路即可。我已经很久没有看到任何设备关心DCD、DTR等了。

你可以看看。它完全符合您的要求,或者如果您有兴趣自己编写一个,那么可以从源代码中查看它的工作原理。

不简单(至少对我来说不简单),但是一种适用于tty串行驱动程序的机制是一个

这里的人已经提出了很好的建议,但还有一个:


您还可以使用自己的
write()
编写一个共享库,在从
libc.so
调用
write()
之前执行一些工作。然后,您可以使用
LD\u PRELOAD
环境变量在进程启动时加载库。

存在
脚本
程序,可以使用psudo终端执行此操作。设备
/dev/tty
通常是特殊的,指的是当前进程的控制终端,因此您可能不必对其进行重命名

script
打开一个psudo终端,然后运行另一个shell实例,将该新shell作为其控制终端(因此
/dev/tty
指此shell及其子进程的此psudo终端)。c选项允许您运行特定命令,而不是shell

script
的主要问题是无法判断输出文件中捕获的数据(默认情况下为
/typescript
)的流向——双向流动的数据转储到同一个文件中,并且看起来与使用交互式终端时屏幕上显示的数据相似(除了包括转义符、回车符、傻乎乎的东西以及通常显示的字符)


无论如何,我知道这个问题早就得到了回答,但我认为如果有人在搜索类似的解决方案时没有使用真正的串行端口,这可能会对他们有所帮助。

问题不是关于std输出。而是关于应用程序写入特定设备,特别是微控制器的链接。关闭,但我不认为这样就可以了。我对输入和输出都感兴趣。应用程序可能会使用一个文件描述符来读取和写入TTY,然后我就遇到了与命名管道相同的问题。TTY不是stdin/stdout。我还希望有一个比使用gdb入侵更小的东西……@Moron那又怎样?你不必选择1作为你替换的fd的编号:)@hobbs:如果它是一个应用程序执行某些ioctl的设备,那么重定向到管道可能不起作用!我希望你现在明白我的意思了。@Moron:说得好——应用程序确实使用ioctl来配置RS-232波特率,这是作弊!:)。当然,这是可行的,但是让RS-232输出与第三方应用程序的stdout调试消息交织在一起对于解决计时问题非常有帮助。很好的建议。我来看看它是如何运行的。它至少完成了一半的工作,而且没有从流中“窃取”数据,尽管它没有显示数据被发送到串行端口。我可能还没有找到正确的选项。令人烦恼的是,我以前至少做过一次(通过ssh记录一个进程),但我找不到任何关于我是如何做的说明,也记不起细节。稍微复杂一点的方法是使用psuedo ttys。模糊的内存表示一对以/dev/tty打开(可能使用符号链接,因为它们有奇怪的名称/dev/pttym和/dev/pttyc),另一端连接到真正的tty设备。更复杂的是,您需要编写一个C包装器,在FDs上进行选择,并在将副本保存到磁盘时来回传递块。s/LDD_PRELOAD/LD_PRELOAD/不幸的是,即使是语法错误修复,也不允许进行单字符编辑,因此我必须使用注释,抱歉。@arielf-您说得对。编辑。虽然5年后回顾这一点,我并不认为这是一个很好的答案。包括实际工作的代码片段(例如,
write
如何避免
    cat /dev/real_tty | tee /dev/tty &