我有一个由第三方开发的与终端通信的Linux进程。为了调试,我希望看到通信来回。
有人可能认为
cat
可以解决问题(看到一个方向):
./third-party-app &
cat /dev/tty
...但事实并非如此。相反,
cat
会窃取应用程序的一半数据,这几乎毫无价值。
第三方应用程序被硬编码为假设
/dev/tty
。
我发现监视通信的一种方法是将
/dev/tty
设备重命名为 /dev/real_tty
,并在其位置创建一个名为 /dev/tty
的命名管道。然后运行:
cat /dev/real_tty | tee /dev/tty &
...至少可以让我看到
/dev/real_tty
的输出,通过将数据从 /dev/real_tty
复制到命名管道 /dev/tty
和 stdout
。
这种方法可行,但感觉非常危险,并且依赖于更换设备的技巧。它也不能在两个方向上工作,因为命名管道仅在一个方向上传输数据。
正确的做法是什么?
如果有人想知道,TTY 设备是与微控制器的 RS-232 链路。该信息不敏感或不安全。所有进程(应用程序和间谍)都可以以 root 身份运行。
您是否考虑过使用strace/ltrace?您可以看到它正在进行的系统调用,特别是您可以看到正在进行的 write/ioctl 等调用。
RS-232?只需用夹子敲击 RxD/TxD/GND 线即可。我已经很久没有见过任何设备关心 DCD、DTR 等了。
你可以看看slsnif。它完全符合您的要求,或者如果您有兴趣自己编写一个,可以使用源代码来了解它是如何工作的。
还有一些替代方案:
使用 GDB 自己动手:从正在运行的进程重定向输出
CryoPID 允许您捕获 Linux 中正在运行的进程的状态并将其保存到文件中。然后,可以使用此文件在重新启动后甚至在另一台计算机上恢复该过程。
分布式多线程检查点是一种透明的工具 对传播的任意一组程序的状态进行检查点 跨多台机器并通过套接字连接。
script
程序可以使用伪终端来执行此操作。设备 /dev/tty
通常很特殊,指的是当前进程的控制终端,因此您可能不必求助于重命名。
script
打开一个伪终端,然后使用该新 shell 作为其控制终端运行 shell 的另一个实例(因此 /dev/tty
指的是该 shell 及其子进程的伪终端)。 -c 选项允许您运行特定命令而不是 shell。
script
的主要问题是无法判断输出文件(默认为./typescript
)中捕获的数据的走向——双向流动的数据被转储到同一个文件中,并且看起来类似于使用交互式终端时出现在屏幕上(除了包含转义符、回车符和类似的愚蠢内容以及正常显示的字符)。
无论如何,我知道这个问题早已得到解答,但我认为如果有人要搜索类似的解决方案并且没有使用真正的串行端口,这可能会对他们有所帮助。
并不简单(至少对我而言),但适用于 tty 串行驱动程序的机制是线路规则。
这里的人已经提出了很好的建议,但这里还有另一个:
您还可以使用自己的
write()
编写一个共享库,该库在从 write()
调用 libc.so
之前执行一些工作。然后,您可以使用 LD_PRELOAD
环境变量在进程启动时加载您的库。
使用socat:
# socat -v -v /dev/real_tty exec:"./third-party-app",pty,ctty,setsid,echo=0
-v
选项应显示 TTY 之间的通信。
这是一个很好的示例参考: