我想知道是否有一个glibc函数,我可以使用gcc / g ++来检索当前的可执行文件。
这样做的目的是为addr2line
提供-e参数,如this answer
答案 0 :(得分:15)
在标准C和glibc中,你有argv [0]:
int main (int argc, char *argv[])
argv
数组的第一个元素是程序名。
然而,确定可执行文件的确切位置并不一定足够。该参数实际上是由运行程序的程序设置的 - 无论是shell还是窗口管理器 - 它们都不是非常有用。如果您的程序在路径中,并且只需使用
运行程序your_program
在bash shell中,然后“your_program”就是argv [0]中的所有内容。
对于完整的可执行文件路径,linux具有/proc
filesystem。在/proc
下,每个正在运行的进程都有自己的“目录”,以其进程ID命名。正在运行的进程也可以在/proc/self
下看到自己的子树。每个进程获取的文件之一是/proc/[pid]/exe
,它是进程运行的实际可执行文件的符号链接。
所以你可以得到这样的实际完整可执行路径:
#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);
}
您也可以将/proc/[pid]/exe
直接传递给addr2line()
。
答案 1 :(得分:7)
您可以通过在glibc中使用已保存的指针来访问argv [0]而不引用实际变量:https://sourceware.org/git/?p=glibc.git;a=blob;f=misc/init-misc.c;h=2a1b82710ec8b42b4dac6edb359d8920f902cd21;hb=HEAD
使用示例:
extern const char *__progname;
int print_progname()
{
return puts(__progname);
}
argv [0]不一定反映用于调用程序的名称。 有关详细信息,请参阅 man 2 execve 和 man 7 environ 。