1

Somewhere in the middle of my application, the framework I'm using (ROOT) gives me the following error:

 *** Break *** write on a pipe with no one to read it
SysError in <TUnixSystem::UnixSend>: send (Broken pipe)
SysError in <TUnixSystem::DispatchOneEvent>: select: read error on 24
 (Bad file descriptor)

How can I check which process is using this file descriptor, preferably without sudo?

5
  • You will not be able to peek into other user's process internals without root obviously. lsof will only show actually useful information for the current user without sudo. Commented Apr 15, 2013 at 17:23
  • the process's are mine Commented Apr 15, 2013 at 17:29
  • File descriptors are numbered per process, not for the system as whole, since a file descriptor is completely internal to a process; it is not shared externally (therefore, system wide references would not make any sense). The connection a file descriptor represents may involve other processes, but not the descriptor itself. Commented Apr 15, 2013 at 17:31
  • @MichaelMrozek There are useful answers in question at SuperUser that may be interesting for future visitors Commented Apr 16, 2013 at 14:02
  • 1
    @RSFalcon7 That's why we discourage crossposting in the first place. They're merged into this post now Commented Apr 16, 2013 at 14:16

3 Answers 3

4

I am afraid that is impossible afterwards. After all "broken pipe" means that the other process is gone (or has at least closed its file descriptor).

While everything is still OK you can do this:

$ sleep 1000 | sleep 1000 & ps
[1] 848156
   PID TTY         TIME CMD
819441 pts/0   00:00:00 bash
848155 pts/0   00:00:00 sleep
848156 pts/0   00:00:00 sleep
848157 pts/0   00:00:00 ps
$ PID=848156 # PID of one of the sleep processes
$ ls -l /proc/$PID/fd
... # Skipped output lines
l-wx------ 1 hl hauke 64 15. Apr 19:11 1 -> pipe:[108237859]
... # Skipped output lines
$ lsof -n | grep 108237859 # gives you all processes which have access to this pipe
sleep     848155     hl    1w     FIFO     0,8     0t0  108237859 pipe
sleep     848156     hl    0r     FIFO     0,8     0t0  108237859 pipe

Edit 1

If lsof is not available:

for dir in /proc/[1-9]*; do
  test -r "$dir"/fd || continue
  if ls -ln "$dir"/fd | grep -q 108237859; then
    echo "PID: ${dir#/proc/}"
  fi
done
4
  • unfortunately lsof is not available in the cluster Commented Apr 15, 2013 at 17:31
  • lsof does nothing magic, it's just convenient to have it do the work. You can do the proc-walk yourself. I edit my answer for better readability. Commented Apr 15, 2013 at 17:45
  • The problem is as you said it is impossible, because the program have lots of files open and I only know the correct file descriptor id after the crash Commented Apr 15, 2013 at 17:57
  • @RSFalcon7 If you want to examine problems that occur with certain processes only then you could watch their /proc/$PID/fd (I don't know whether fileschanged works in /proc; that would be great), log changes and find the respective other process(es) when a new pipe occurs. Commented Apr 15, 2013 at 18:00
2

The lsof command will show you opened descriptors, then just grep it.

2
  • lsof is not installed in the cluster Commented Apr 15, 2013 at 17:29
  • then you can also use pidoff and look into the /proc/<processid>/fd (guessing the path right now, but it's something like that) Commented Apr 15, 2013 at 17:33
1

Without lsof you could try:

find /proc -name <descriptor> | grep fdinfo

It should return some results of the form ./<pid>/fdinfo/<fd>

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.