识别unix域套接字连接的另一端

时间:2012-08-10 08:03:46

标签: linux kernel unix-socket

我正在试图弄清楚哪个进程占据了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]

但是,这些都没有告诉我套接字连接的其他结尾是什么。如何判断哪个进程占据另一端?

2 个答案:

答案 0 :(得分:15)

Server FaultUnix & 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

相关问题