1

I am writing a C shared library in Linux in which a function would like to discover the path to the currently running executable. It does NOT have access to argv[0] in main(), and I don't want to require the program accessing the library to pass that in.

How can a function like this, outside main() and in the wild, get to the path of the running executable? So far I've thought of 2 rather unportable, unreliable ways: 1) try to read /proc/getpid()/exe and 2) try to climb the stack to __libc_start_main() and read the stack params. I worry about all machines having /proc mounted.

Can you think of another way? Is there something buried anywhere in dlopen(NULL, 0) ? Can I get a reliable proc image of self from the kernel??

Thanks for any thoughts.

  • http://stackoverflow.com/questions/1023306/finding-current-executables-path-without-proc-self-exe – user3159253 Apr 17 '14 at 02:51
  • And likely argv[0] isn't a reliable way anyway because the name given there may be relative to the current working directory _at the start_ of the process – user3159253 Apr 17 '14 at 02:53
  • Note that not all non-Linux systems have `/proc` (e.g. Mac OS X does not have it), and those that do don't necessarily have the same structure as Linux (e.g. Solaris, at least in older versions). – Jonathan Leffler Apr 17 '14 at 03:27

2 Answers2

1

/proc is your best chance, as "path of the executable" is not that well defined concept in Linux (you can even delete it while the program is running).

To get the breakdown of loaded modules (with the main executable usually being the first entry) you should look at /proc/<pid>/maps. It's a text formatted file which will allow you to associate executable and library paths with load addresses (if the former are known and still valid).

oakad
  • 6,945
  • 1
  • 22
  • 31
1

Unless you are writing software that may be used very early in system startup, you can safely assume that /proc will always be mounted on a Linux system. It contains quite a bit of data that is not accessible any other way, and thus must be mounted for a system to function properly. As such, you can pretty easily obtain a path to your executable using:

readlink("/proc/self/exe", buf, sizeof(buf));

If for some reason you want to avoid this, it's also possible to read it from the process's auxiliary vector:

#include <sys/auxv.h>
#include <elf.h>

const char *execpath = (const char *) getauxval(AT_EXECFN);

Note that this will require a recent version of glibc (2.16 or later). It'll also return the path that was used to execute your application (e.g, possibly something like ./binary), rather than its absolute path.