When debugging inter-process communication via UNIX domain sockets, one common challenge is tracing both ends of a socket connection. The example shows a dbus-daemon (PID 23284) with multiple connections, where we specifically want to identify the client process using file descriptor 36.
We begin by examining the file descriptor:
ls -l /proc/23284/fd/36
lrwx------ 1 depesz depesz 64 2011-03-28 15:32 /proc/23284/fd/36 -> socket:[1013410]
The socket inode number (1013410) is our key identifier for tracing the connection.
For modern Linux systems, these methods provide the most reliable results:
Method 1: Using ss (Socket Statistics)
ss -xp | grep 1013410
This will show both ends of the connection with process information. The -x
flag limits to UNIX sockets, while -p
shows process information.
Method 2: lsof with Inode Filter
lsof -U | grep 1013410
Or more precisely:
lsof -Ua +E -i | grep 1013410
Method 3: Direct /proc Inspection
For systems where root access is available:
grep -l 1013410 /proc/*/fd/* 2>/dev/null
Here's a complete debugging session example:
# Find socket inode
ls -l /proc/23284/fd/36
# Get connection details
ss -xp | grep 1013410
# Sample output:
# unix 3 [ ] STREAM CONNECTED 1013410 23284/dbus-daemon @/tmp/dbus-3XDU4PYEzD
# unix 3 [ ] STREAM CONNECTED 1013410 12345/client-process
For frequent debugging, consider this bash function:
find_socket_peer() {
local pid=$1
local fd=$2
local inode=$(readlink /proc/$pid/fd/$fd | grep -oP 'socket:$$\K\d+$$')
if [[ -z "$inode" ]]; then
echo "Not a socket"
return 1
fi
echo "Socket inode: $inode"
echo "Connected processes:"
ss -xp | grep "$inode"
}
For DBUS connections specifically, you can also use:
dbus-monitor --address unix:path=/tmp/dbus-3XDU4PYEzD
This won't show the process information but can help understand the communication.
Once you identify the potential client process, verify by checking its open files:
ls -l /proc/<client_pid>/fd/ | grep socket
Look for the same inode number (1013410 in our example) to confirm the connection.
When working with UNIX domain sockets in Linux, you might encounter situations where you need to identify both ends of a socket connection, particularly when debugging inter-process communication. The example shows a dbus-daemon process with multiple socket connections, and we need to find which client process is connected via file descriptor #36.
First, let's understand how to examine socket connections from both system-wide and process-specific perspectives:
# System-wide view of UNIX sockets
ss -xap | grep dbus-daemon
# Process-specific file descriptors
ls -l /proc/23284/fd/
To find the other end of a specific socket connection (inode 1013410 in our example), we can use these approaches:
# Method 1: Using lsof
lsof -U | grep 1013410
# Method 2: Parsing /proc/net/unix
grep "1013410" /proc/net/unix
# Method 3: Using ss with advanced filtering
ss -xap -e src inode=1013410
Here's a more robust approach that handles permission issues and provides complete information:
#!/bin/bash
# Get socket inode from process FD
INODE=$(readlink /proc/23284/fd/36 | sed 's/socket:$\(.*$\]/\1/')
# Find the peer connection
find_peer() {
# Check all processes
for pid in /proc/[0-9]*; do
pid=${pid#/proc/}
# Skip if not a valid PID
[ "$pid" -eq "$pid" ] 2>/dev/null || continue
# Check all file descriptors
for fd in /proc/$pid/fd/*; do
if [ -L "$fd" ]; then
link_target=$(readlink "$fd")
if [[ "$link_target" == *"$INODE"* ]]; then
echo "Found peer process:"
ps -p $pid -o pid,cmd
return 0
fi
fi
done
done
echo "No peer process found"
return 1
}
find_peer
For systems with many connections, we can optimize the search:
# Using inotifywait to monitor socket creation
inotifywait -m /tmp -e create |
while read path action file; do
if [[ "$file" == dbus-* ]]; then
echo "New DBus socket created: $file"
ss -xap src "/tmp/$file"
fi
done
When standard tools don't show the peer connection:
- Run commands as root to see all processes
- Check if the connection is already closed
- Use strace to monitor socket activity
strace -p 23284 -e trace=network -s 1000