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

时间:2022-07-05 21:05:56

I have a Linux process developed by a third-party that communicates with a terminal. For debugging I want to see the communication going back in forth.

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

One might think cat would do the trick (to see one direction):

有人可能会认为猫可以做到这一点(看一个方向):

    ./third-party-app &
    cat /dev/tty

...but it does not. Rather, cat will steal half of the data intended for the application, which is pretty much worthless.

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

third-party-app is hard-coded to assume /dev/tty.

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

One way I found to spy on the communication is to rename the /dev/tty device to, say, /dev/real_tty and create a named pipe called /dev/tty in its place. Then running:

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

    cat /dev/real_tty | tee /dev/tty &

...will at least let me see the output of /dev/real_tty, by copying the data from /dev/real_tty to the named pipe /dev/tty and stdout.

...至少让我看到/ dev / real_tty的输出,方法是将数据从/ dev / real_tty复制到命名管道/ dev / tty和stdout。

This sort of works but it feels really dodgy, and relies on the trickery of replacing the device. It also doesn't work in both directions, because named pipes only carry data in one direction.

这种工作但它感觉非常狡猾,并依赖于更换设备的技巧。它也不能在两个方向上工作,因为命名管道只在一个方向上传输数据。

What's the right way to do this?

这样做的正确方法是什么?

If anyone's wondering, the TTY device is a RS-232 link to a microcontroller. The information is not sensitive or secured. All processes (application and spies) can run as root.

如果有人想知道,TTY设备是微控制器的RS-232链接。信息不敏感或不安全。所有进程(应用程序和间谍)都可以以root身份运行。

7 个解决方案

#1


1  

You could take a look at slsnif. It does exactly what you want, or if you're interested in writing one yourself the source is available to see how it works.

你可以看看slsnif。它完全符合您的要求,或者如果您有兴趣自己编写,可以查看其工作原理。

#2


3  

Have you considered using strace/ltrace? You can see the system calls it is making, in particular you can see the write/ioctl etc calls being made.

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

#3


2  

RS-232? Just tap the RxD/TxD/GND lines with clips. It's been a forever since I've seen any device even care about DCD, DTR, etc.

RS-232?只需用夹子敲击RxD / TxD / GND线。这是一个永远,因为我看到任何设备甚至关心DCD,DTR等。

#4


1  

There are some alternatives:

有一些替代方案:

Do It Youself with GDB: Redirecting Output from a Running Process

使用GDB自己动手:从正在运行的进程重定向输出

CryoPID allows you to capture the state of a running process in Linux and save it to a file. This file can then be used to resume the process later on, either after a reboot or even on another machine.

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

Distributed MultiThreaded CheckPointing is a tool to transparently checkpointing the state of an arbitrary group of programs spread across many machines and connected by sockets.

分布式MultiThreaded CheckPointing是一种透明地检查分布在许多机器上并通过套接字连接的任意程序组状态的工具。

#5


1  

The script program exists to do this using psudo-terminal. The device /dev/tty is usually special and refers to the current process's controlling terminal, so you may not have had to resort to renaming things.

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

script opens a psudo-terminal and then runs another instance of your shell with that new shell as its controlling terminal (so /dev/tty refers to this psudo-terminal for this shell and its child processes). The -c option lets you run a particular command rather than your shell.

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

The main problem with script is that it is impossible to tell which way the data captured in the output file (./typescript by default) was going -- data flowing both ways is dumped to the same file and looks similar to what appears on the screen when using an interactive terminal (except for including escapes, carriage returns, and goofy stuff like that as well as the normally displayed characters).

脚本的主要问题是无法确定输出文件中捕获的数据的方式(默认情况下为./typescript) - 双向流动的数据被转储到同一个文件中,看起来类似于使用交互式终端时的屏幕(除了包括转义,回车,像这样的愚蠢的东西以及正常显示的字符)。

Anyway, I know that this question has long since been answered, but I thought that if anyone were to search for a similar solution and were not using a real serial port this may help them.

无论如何,我知道这个问题早已得到解答,但我认为如果有人要搜索类似的解决方案并且没有使用真正的串口,这可能对他们有所帮助。

#6


0  

Not simple (not for me at least), but a mechanism that should work for the tty serial drivers is a line discipline.

不简单(至少不适合我),但应该适用于tty串行驱动程序的机制是一个线路规则。

#7


0  

People here have already made good suggestions, but here's another:

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

You can also write a shared library with your own write() that does some work before calling the write() from libc.so. Then you can use the LD_PRELOAD environment variable to load your library when the process starts.

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

#1


1  

You could take a look at slsnif. It does exactly what you want, or if you're interested in writing one yourself the source is available to see how it works.

你可以看看slsnif。它完全符合您的要求,或者如果您有兴趣自己编写,可以查看其工作原理。

#2


3  

Have you considered using strace/ltrace? You can see the system calls it is making, in particular you can see the write/ioctl etc calls being made.

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

#3


2  

RS-232? Just tap the RxD/TxD/GND lines with clips. It's been a forever since I've seen any device even care about DCD, DTR, etc.

RS-232?只需用夹子敲击RxD / TxD / GND线。这是一个永远,因为我看到任何设备甚至关心DCD,DTR等。

#4


1  

There are some alternatives:

有一些替代方案:

Do It Youself with GDB: Redirecting Output from a Running Process

使用GDB自己动手:从正在运行的进程重定向输出

CryoPID allows you to capture the state of a running process in Linux and save it to a file. This file can then be used to resume the process later on, either after a reboot or even on another machine.

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

Distributed MultiThreaded CheckPointing is a tool to transparently checkpointing the state of an arbitrary group of programs spread across many machines and connected by sockets.

分布式MultiThreaded CheckPointing是一种透明地检查分布在许多机器上并通过套接字连接的任意程序组状态的工具。

#5


1  

The script program exists to do this using psudo-terminal. The device /dev/tty is usually special and refers to the current process's controlling terminal, so you may not have had to resort to renaming things.

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

script opens a psudo-terminal and then runs another instance of your shell with that new shell as its controlling terminal (so /dev/tty refers to this psudo-terminal for this shell and its child processes). The -c option lets you run a particular command rather than your shell.

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

The main problem with script is that it is impossible to tell which way the data captured in the output file (./typescript by default) was going -- data flowing both ways is dumped to the same file and looks similar to what appears on the screen when using an interactive terminal (except for including escapes, carriage returns, and goofy stuff like that as well as the normally displayed characters).

脚本的主要问题是无法确定输出文件中捕获的数据的方式(默认情况下为./typescript) - 双向流动的数据被转储到同一个文件中,看起来类似于使用交互式终端时的屏幕(除了包括转义,回车,像这样的愚蠢的东西以及正常显示的字符)。

Anyway, I know that this question has long since been answered, but I thought that if anyone were to search for a similar solution and were not using a real serial port this may help them.

无论如何,我知道这个问题早已得到解答,但我认为如果有人要搜索类似的解决方案并且没有使用真正的串口,这可能对他们有所帮助。

#6


0  

Not simple (not for me at least), but a mechanism that should work for the tty serial drivers is a line discipline.

不简单(至少不适合我),但应该适用于tty串行驱动程序的机制是一个线路规则。

#7


0  

People here have already made good suggestions, but here's another:

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

You can also write a shared library with your own write() that does some work before calling the write() from libc.so. Then you can use the LD_PRELOAD environment variable to load your library when the process starts.

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