30

If I start a process and then delete the binary of it, I can still recover it from /proc/<pid>/exe:

$ cp `which sleep` .
$ ./sleep 10m &
[1] 13728
$ rm sleep
$ readlink /proc/13728/exe                           
/tmp/sleep (deleted)
$ cp /proc/13728/exe ./sleep-copy
$ diff sleep-copy `which sleep` && echo not different
not different
$ stat /proc/13728/exe 
  File: ‘/proc/13728/exe’ -> ‘/tmp/sleep (deleted)’
  Size: 0           Blocks: 0          IO Block: 1024   symbolic link

On the other hand, if I make a symbolic link myself, delete the target and attempt to copy:

cp: cannot stat ‘sleep’: No such file or directory

/proc is an interface to the kernel. So does this symbolic link actually point to the copy loaded in memory, but with a more useful name? How does the exe link work, exactly?

0

3 Answers 3

27

/proc/<pid>/exe does not follow the normal semantics for symbolic links. Technically this might count as a violation of POSIX, but /proc is a special filesystem after all.

/proc/<pid>/exe appears to be a symlink when you stat it. This is a convenient way for the kernel to export the pathname it knows for the process' executable. But when you actually open that "file", there is none of the normal procedure of reading the following the contents of a symlink. Instead the kernel just gives you access to the open file entry directly.

Notice that when you ls -l a /proc/<pid>/exe pseudofile for a process whose executable has been deleted the symlink target has the string " (deleted)" at the end of it. This would normally be non-sensical in a symlink: there definitely isn't a file that lives at the target path with a name that ends with " (deleted)".

tl;dr The proc filesystem implementation just does its own magic thing with pathname resolution.

2
  • 1
    And the magic lives in proc_exe_link() in the proc filesystem: lxr.free-electrons.com/source/fs/proc/base.c?v=4.0#L1350 Apr 22, 2015 at 22:09
  • How do you know there definitely isn't a file with such a name? Someone might have created one as an experiment; I've done it once before. Not very likely it would exist for any other reason, but still not impossible.
    – flarn2006
    Dec 4, 2018 at 18:53
5

According to the man page of /proc, under Linux 2.2 and later, the file is a symbolic link containing the actual pathname of the executed command. Apparently, the binary is loaded into memory, and /proc/[pid]/exe points to the content of the binary in memory.

On the other hand, under Linux 2.0 and earlier, /proc/[pid]/exe is apparently a pointer to the file (in the filesystem) which was executed.

So if you ran the same list of commands on Linux 2.0 or earlier, presumably you would get an error "no such file or directory".

2
  • Which manpage? linux.die.net/man/5/proc and manpages.ubuntu.com/manpages/utopic/en/man5/proc.5.html say "attempting to open it will open the executable", but doesn't say where it comes from.
    – muru
    Apr 22, 2015 at 14:30
  • 2
    I'm pretty sure the kernel gives you the content of the inodes for the binary, rather than its in-memory copy. The in-memory copy is unlikely to contain all of the sections of the file. The inodes, on the other hand, are reference-counted and won't be overwritten while references exist. The kernel will keep a reference to executing files so it can load additional sections if necessary.
    – Mark
    May 10, 2016 at 16:40
4

All files in /proc are generated on demand. They sometimes behave slightly differently from ordinary files because of that.

For example, many files in /proc appear as regular files with a size of 0 in directory listings. Yet, when you read from them, they aren't empty. The reason is that the content of the file is generated on demand. The content can vary over time and can even depend on the process that opens the file. So there's no way to know the size of the content without opening the file and reading from it.

/proc/<pid>/exe is a reference to an open file description inside the kernel. There's no way to convey an open file description exactly: it's a data structure inside the kernel. So the kernel represents it in an approximate way: as a symbolic link to the file. The kernel remembers the name of the file, and even keeps track of the file if it's renamed thanks to information maintained by the abstract filesystem layer. If the file is deleted, the kernel remembers the last name it knew and appends (deleted) to the name. The string that is returned as the target of the symbolic link is generated on the fly each time a process calls readlink on it. Under the hood, opening /proc/<pid>/exe shortcuts the usual symbolic link resolution and directly opens the file description. The same applies to /proc/<pid>/fd/<number>, /proc/<pid>/cwd, /proc/<pid>/root and other similar links.

Another example of a “magic” symbolic link is /proc/self. It's generated on the fly to point to the /proc/<pid> directory of the process that accesses it.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .