【问题标题】:Identify other end of a unix domain socket connection识别 Unix 域套接字连接的另一端
【发布时间】:2012-08-07 12:28:04
【问题描述】:

我正在尝试找出哪个进程正在持有 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]

但是,这些都不能告诉我套接字连接的 other 端是什么。我如何知道哪个进程在控制另一端?

【问题讨论】:

标签: linux kernel unix-socket


【解决方案1】:

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

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

如果调试信息不​​可用,可能可以通过了解对等成员在 unix_sock 结构中的偏移量来访问所需的信息。在我的例子中,在 x86_64 的 Linux 3.5.0 上,可以使用以下代码来计算相同的地址,而无需依赖调试符号:

(gdb) p ((void**)0xffff8803e256d9c0)[0x52]

我不会对该解决方案的便携性做出任何保证。

【讨论】:

  • 也许,这个解决方案可以转换成一个内核模块(或工具),可针对内核头文件或与加载的内核对应的源代码进行编译......
  • 嗯,有一些补丁提交给 linux 会暴露这些信息,但它们没有被合并... -- reddit.com/r/linux/comments/ikizs/…
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 2011-12-27
    • 2012-04-11
    • 1970-01-01
    • 2017-02-06
    • 1970-01-01
    • 1970-01-01
    • 2019-02-12
    • 2013-02-05
    • 1970-01-01
    相关资源
    最近更新 更多