我的Linux系统上有一个进程,使用strace告诉我它在与文件描述符10对应的套接字通信。lsof告诉我这是一个带有inode 11085的Unix套接字,而netstat进一步告诉我inode 11085是一个流套接字,并且它已连接。
考虑到该进程没有其他线程,因此必须有另一个进程连接到此套接字的另一端。我该如何找到它是哪个进程?
更新:从lsof的作者这里得到了一些启示。本质上,似乎Linux没有提供这个信息。
ss -p
会告诉你。(前提是该套接字不属于内核本身。)
/usr/bin/ss
位于iproute2
软件包中。 - daf你是否需要使用netstat -p
命令?
来自Manpage:
-p,
--program Show the PID and name of the program to which each socket belongs.
-p
开关。请参见选项CONFIG_FEATURE_NETSTAT_PRG
,通过busybox menuconfig选择Networking Utilities → netstat → Enable PID/Program name output进行选择。 - Craig McQueengrep 11085 /proc/net/unix
。假设您感兴趣的inode所在的行中存在非空路径,则可以在/proc/net/unix
上搜索该路径以查找连接另一端的inode,然后使用@efficientjelly的方法将其他inode映射到pid
。关键点在于两个连接套接字各自具有不同的inode号码。我观察到:
在客户端调用connect()
时,文件描述符fd
的Inode始终比服务器端accept()
调用返回的Inode多1。
我的程序示例输出:
client_fd=4
/proc/4436/fd/4
inode=3072
is socket
node: 3072 socket: /tmp/unix.socket
f0be8960: 00000003 00000000 00000000 0001 03 3072 /tmp/unix.socket
/proc/9293/fd/43
fd:43
inode=3073
is socket
node: 3073 socket:
f0be81e0: 00000003 00000000 00000000 0001 03 3073
/proc/net/unix
中显示。# socket_peer 11085
3703 thunderbird
netstat_unix
,它会在netstat的输出中添加一列:# netstat_unix
Proto RefCnt Flags Type State I-Node PID/Program name Peer PID/Program name Path
unix 3 [ ] STREAM CONNECTED 6825 982/Xorg 1497/compiz /tmp/.X11-unix/X0
unix 3 [ ] STREAM CONNECTED 6824 1497/compiz 982/Xorg
unix 3 [ ] SEQPACKET CONNECTED 207142 3770/chromium-brows 17783/UMA-Session-R
unix 3 [ ] STREAM CONNECTED 204903 1523/pulseaudio 3703/thunderbird
unix 3 [ ] STREAM CONNECTED 204902 3703/thunderbird 1523/pulseaudio
unix 3 [ ] STREAM CONNECTED 204666 1523/pulseaudio 3703/thunderbird
...
netstat_unix --dump
。vmlinux
映像(例如安装kernel-debuginfo
rpm或从该rpm中提取vmlinux
文件)
- 运行crash /path/to/vmlinux
- net -s 12345
列出PID
为12345的所有套接字
- 找到有趣的套接字(必须是UNIX:STREAM
家族/类型),并注意其SOCK
值:PID: 12345 TASK: e903d000 CPU: 0 COMMAND: "someapp"
- FD SOCKET SOCK FAMILY:TYPE SOURCE-PORT DESTINATION-PORT
- 36 cadd0240 c8a64040 UNIX:STREAM
- 现在你拥有了这个套接字的unix_sock struct
的地址unix_sock.peer.name
是套接字另一端的名称结构
- 使用:p *(*(*((struct unix_sock*)( (struct unix_sock*)0xc8a64040)->peer)).addr).name
打印它如果您使用适当的lsof和netstat选项仍然无法解决问题,您还可以执行以下操作:
find /proc -lname '*11085*' 2> /dev/null
find /proc -type l
; do readlink "$i" | grep -q 11085 && echo "$i"; done
/proc/1892/task/1892/fd/10
/proc/1892/fd/10因此,只有原始进程出现。 - daflsof | grep 11085
需要以root身份执行lsof。
我一直在我的Linux系统上尝试使用lsof,lsof -U
显示列NODE下的所有数字都是唯一的。