我正在试图弄清楚哪个进程占据了unix域套接字的另一端。在一些strace
输出中,我已经确定了一个给定的文件描述符,它涉及我正在调试的问题,并且我想知道哪一个进程在另一端。由于与该套接字有多个连接,因此只需按路径名进行操作即可。
lsof
向我提供了以下信息:
dbus-daem 4175 mvg 10u unix 0xffff8803e256d9c0 0t0 12828 @/tmp/dbus-LyGToFzlcG
所以我知道一些地址(“内核地址”?),我知道一些套接字号,我知道路径。我可以在其他地方找到相同的信息:
$ netstat -n | grep 12828
unix 3 [ ] STREAM CONNECTED 12828 @/tmp/dbus-LyGToFzlcG
$ grep -E '12828|ffff8803e256d9c0' /proc/net/unix
ffff8803e256d9c0: 00000003 00000000 00000000 0001 03 12828 @/tmp/dbus-LyGToFzlcG
$ ls -l /proc/*/fd/* 2>/dev/null | grep 12828
lrwx------ 1 mvg users 64 10. Aug 09:08 /proc/4175/fd/10 -> socket:[12828]
但是,这些都没有告诉我套接字连接的其他结尾是什么。如何判断哪个进程占据另一端?
答案 0 :(得分:15)
Server Fault和Unix & Linux提出了类似的问题。接受的答案是Linux上的用户空间无法可靠地获取此信息。
一个常见的建议是查看相邻的套接字号,但ls -l /proc/*/fd/* 2>/dev/null | grep 1282[79]
在这里没有给出结果。也许可以使用netstat
输出中的相邻行。似乎有一个带有和没有相关套接字名称的连接模式。但我想要某种确定性,而不仅仅是猜测。
One answer建议使用一种工具,通过挖掘内核结构来解决这个问题。使用该选项需要内核的调试信息,由CONFIG_DEBUG_INFO
选项生成,并由某些发行版作为单独的包提供。基于该答案,使用lsof
提供的地址,以下解决方案对我有用:
# gdb /usr/src/linux/vmlinux /proc/kcore
(gdb) p ((struct unix_sock*)0xffff8803e256d9c0)->peer
这将打印连接另一端的地址。为该数字加注lsof -U
将提供有关进程ID和文件描述符编号的详细信息。
如果调试信息不可用,则可能可以通过了解对等成员到unix_sock结构的偏移量来访问所需信息。就我而言,在Linux 3.5.0 for x86_64上,可以使用以下代码计算相同的地址,而不依赖于调试符号:
(gdb) p ((void**)0xffff8803e256d9c0)[0x52]
我不会保证解决方案的可移植性。
答案 1 :(得分:1)
更新:现在可以使用实际接口执行此操作。从Linux 3.3开始,UNIX_DIAG功能为此信息提供了基于netlink的API,而lsof 4.89及更高版本支持它。有关详细信息,请参阅https://unix.stackexchange.com/a/190606/1820。