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

MvG*_*MvG 18 linux kernel unix-socket

我正在试图弄清楚哪个进程占据了unix域套接字的另一端.在某些strace输出中,我已经确定了一个给定的文件描述符,它涉及我正在调试的问题,而且我想知道哪一个进程在另一端.由于与该套接字有多个连接,因此只需按路径名进行操作即可.

lsof 向我提供以下信息:

dbus-daem  4175  mvg   10u  unix 0xffff8803e256d9c0      0t0  12828 @/tmp/dbus-LyGToFzlcG
Run Code Online (Sandbox Code Playgroud)

所以我知道一些地址("内核地址"?),我知道一些套接字号,我知道路径.我可以在其他地方找到相同的信息:

$ 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]
Run Code Online (Sandbox Code Playgroud)

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

MvG*_*MvG 15

Server FaultUnix&Linux上也提出了类似的问题.接受的答案是Linux上的用户空间无法可靠地获取此信息.

一个常见的建议是查看相邻的套接字号,但ls -l /proc/*/fd/* 2>/dev/null | grep 1282[79]这里没有给出结果.也许netstat可以使用输出中的相邻行.似乎有一个带有和没有相关套接字名称的连接模式.但我想要某种确定性,而不仅仅是猜测.

一个答案表明,一种工具似乎能够通过挖掘内核结构来解决这个问题.使用该选项需要内核的调试信息,由CONFIG_DEBUG_INFO选项生成,并由某些发行版作为单独的包提供.基于该答案,使用提供的地址lsof,以下解决方案为我工作:

# gdb /usr/src/linux/vmlinux /proc/kcore
(gdb) p ((struct unix_sock*)0xffff8803e256d9c0)->peer
Run Code Online (Sandbox Code Playgroud)

这将打印连接另一端的地址.对该lsof -U数字进行Grepping 将提供进程ID和文件描述符编号等详细信息.

如果调试信息不​​可用,则可以通过了解对等成员到unix_sock结构的偏移量来访问所需信息.就我而言,在Linux 3.5.0 for x86_64上,以下代码可用于计算相同的地址,而不依赖于调试符号:

(gdb) p ((void**)0xffff8803e256d9c0)[0x52]
Run Code Online (Sandbox Code Playgroud)

我不会对该解决方案的可移植性做出任何保证.


Sam*_*amB 2

更新:现在可以使用实际界面来做到这一点一段时间了。从 Linux 3.3 开始,UNIX_DIAG 功能为此信息提供了基于 netlink 的 API,lsof 4.89 及更高版本支持它。有关更多信息,请参阅https://unix.stackexchange.com/a/190606/1820 。