glibc function to retrieve current executable name?

烂漫一生 提交于 2019-11-30 05:03:45

In standard C and glibc, you have argv[0]:

int main (int argc, char *argv[])

the first element of the argv array is the program name.

However it's not necessarily enough on its own to determine where exactly the executable is. The argument is actually set by the program that ran your program - be it a shell or a window manager - and they aren't terribly helpful. If your program is in the path and you run the program simply with

your_program

at a bash shell, then "your_program" is all you will get in argv[0].

For the full executable path, linux has the /proc filesystem. Under /proc each running process gets its own "directory", named by its process id. The running process can also see its own subtree under /proc/self. One of the files that each process gets is /proc/[pid]/exe, which is a symbolic link to the actual executable the process is running.

So you can get the actual full executable path like this:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>

int main(void) {
    char exe[1024];
    int ret;

    ret = readlink("/proc/self/exe",exe,sizeof(exe)-1);
    if(ret ==-1) {
        fprintf(stderr,"ERRORRRRR\n");
        exit(1);
    }
    exe[ret] = 0;
    printf("I am %s\n",exe);
}

You may also be able to pass /proc/[pid]/exe directly to addr2line().

badeip

You can access argv[0] without a reference to the actual variable, by using a saved pointer in glibc: https://sourceware.org/git/?p=glibc.git;a=blob;f=misc/init-misc.c;h=2a1b82710ec8b42b4dac6edb359d8920f902cd21;hb=HEAD

Example usage:

extern const char *__progname;

int print_progname()
{
    return puts(__progname);
}

argv[0] does not necessarily reflect the name that was used to invoke the program though. See man 2 execve and man 7 environ for more information.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!