标识unix域套接字连接的其他端

时间:2022-03-12 07:37:21

I'm trying to figure out what process is holding the other end of a unix domain socket. In some strace output I've identified a given file descriptor which is involved in the problem I'm currently debugging, and I'd like to know which process is on the other end of that. As there are multiple connections to that socket, simply going by path name won't work.

我试图弄清楚哪个进程在unix域套接字的另一端。在一些strace输出中,我已经确定了一个给定的文件描述符,它与我正在调试的问题有关,我想知道另一端是哪个进程。由于有多个连接到该套接字,仅使用路径名是行不通的。

lsof provides me with the following information:

lsof可以向我提供以下信息:

dbus-daem  4175  mvg   10u  unix 0xffff8803e256d9c0      0t0  12828 @/tmp/dbus-LyGToFzlcG

So I know some address (“kernel address”?), I know some socket number, and I know the path. I can find that same information in other places:

我知道某个地址(“内核地址”?),知道某个套接字号,知道路径。我可以在其他地方找到同样的信息:

$ 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]

However, none of this tells me what the other end of my socket connection is. How can I tell which process is holding the other end?

然而,这些都不能告诉我套接字连接的另一端是什么。我怎么知道哪个过程在另一端?

2 个解决方案

#1


1  

Update: It's been possible to to do this using actual interfaces for a while now. Starting with Linux 3.3, the UNIX_DIAG feature provides a netlink-based API for this information, and lsof 4.89 and later support it. See https://unix.stackexchange.com/a/190606/1820 for more information.

更新:现在可以使用实际的接口来实现这一点。从Linux 3.3开始,UNIX_DIAG特性就为这些信息提供了基于网络的API, lsof 4.89以及以后的支持。更多信息请参见https://unix.stackexchange.com/a/190606/1820。

#2


15  

Similar questions have been asked on Server Fault and Unix & Linux. The accepted answer is that this information is not reliably available to the user space on Linux.

关于服务器故障和Unix和Linux也有类似的问题。公认的答案是,Linux上的用户空间不能可靠地获得这些信息。

A common suggestion is to look at adjacent socket numbers, but ls -l /proc/*/fd/* 2>/dev/null | grep 1282[79] gave no results here. Perhaps adjacent lines in the output from netstat can be used. It seems like there was a pattern of connections with and without an associated socket name. But I'd like some kind of certainty, not just guesswork.

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

One answer suggests a tool which appears to be able to address this by digging through kernel structures. Using that option requires debug information for the kernel, as generated by the CONFIG_DEBUG_INFO option and provided as a separate package by some distributions. Based on that answer, using the address provided by lsof, the following solution worked for me:

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

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

This will print the address of the other end of the connection. Grepping lsof -U for that number will provide details like the process id and the file descriptor number.

这将打印连接的另一端的地址。为这个数字添加lsof -U将提供诸如进程id和文件描述符号之类的详细信息。

If debug information is not available, it might be possible to access the required information by knowing the offset of the peer member into the unix_sock structure. In my case, on Linux 3.5.0 for x86_64, the following code can be used to compute the same address without relying on debugging symbols:

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

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

I won't make any guarantees about how portable that solution is.

我不会保证这个解决方案的可移植性。

#1


1  

Update: It's been possible to to do this using actual interfaces for a while now. Starting with Linux 3.3, the UNIX_DIAG feature provides a netlink-based API for this information, and lsof 4.89 and later support it. See https://unix.stackexchange.com/a/190606/1820 for more information.

更新:现在可以使用实际的接口来实现这一点。从Linux 3.3开始,UNIX_DIAG特性就为这些信息提供了基于网络的API, lsof 4.89以及以后的支持。更多信息请参见https://unix.stackexchange.com/a/190606/1820。

#2


15  

Similar questions have been asked on Server Fault and Unix & Linux. The accepted answer is that this information is not reliably available to the user space on Linux.

关于服务器故障和Unix和Linux也有类似的问题。公认的答案是,Linux上的用户空间不能可靠地获得这些信息。

A common suggestion is to look at adjacent socket numbers, but ls -l /proc/*/fd/* 2>/dev/null | grep 1282[79] gave no results here. Perhaps adjacent lines in the output from netstat can be used. It seems like there was a pattern of connections with and without an associated socket name. But I'd like some kind of certainty, not just guesswork.

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

One answer suggests a tool which appears to be able to address this by digging through kernel structures. Using that option requires debug information for the kernel, as generated by the CONFIG_DEBUG_INFO option and provided as a separate package by some distributions. Based on that answer, using the address provided by lsof, the following solution worked for me:

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

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

This will print the address of the other end of the connection. Grepping lsof -U for that number will provide details like the process id and the file descriptor number.

这将打印连接的另一端的地址。为这个数字添加lsof -U将提供诸如进程id和文件描述符号之类的详细信息。

If debug information is not available, it might be possible to access the required information by knowing the offset of the peer member into the unix_sock structure. In my case, on Linux 3.5.0 for x86_64, the following code can be used to compute the same address without relying on debugging symbols:

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

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

I won't make any guarantees about how portable that solution is.

我不会保证这个解决方案的可移植性。