从C库中获取当前的执行路径

伪心理

我正在用C语言编写一个记录器库,目前正在尝试使用来获得更好的回溯输出addr2line为此,我需要能够获取当前可执行文件的路径。目前,我只关心linux,但也会争取Mac OS的支持。

对于linux支持,我试图使用readlink()/proc/self/exe解决当前可执行文件的路径:

static char** getPrettyBacktrace( void* addresses[], int array_size ) {
    // Used to return the strings generated from the addresses
    char** backtrace_strings = (char**)malloc( sizeof( char ) * array_size );
    for( int i = 0; i < array_size; i ++ ) {
        backtrace_strings[i] = (char*)malloc( sizeof( char ) * 255 );
    }

    // Will hold the command to be used
    char* command_string    = (char*)malloc( 255 );
    char* exe_path          = (char*)malloc( 255 );

    // Used to check if an error occured while setting up command
    bool error = false;

    // Check if we are running on Mac OS or not, and select appropriate command
    char* command;
    #ifdef __APPLE__
        // Check if 'gaddr2line' function is available, if not exit
        if( !system( "which gaddr2line > /dev/null 2>&1" ) ) {
            command = "gaddr2line -Cfspe";
            // TODO: get path for mac with 'proc_pidpath'
        } else {
            writeLog( SIMPLOG_LOGGER, "Function 'gaddr2line' unavailable. Defaulting to standard backtrace. Please install package 'binutils' for better stacktrace output." );
            error = true;
        }
    #else
        // Check if 'addr2line' function is available, if not exit
        if( !system( "which addr2line > /dev/null 2>&1" ) ) {
            command = "addr2line -Cfspe";
            if( readlink( "/proc/self/exe", exe_path, sizeof( exe_path ) ) < 0 ) {
                writeLog( SIMPLOG_LOGGER, "Unable to get execution path. Defaulting to standard backtrace." );
                error = true;
            }
        } else {
            writeLog( SIMPLOG_LOGGER, "Function 'addr2line' unavailable. Defaulting to standard backtrace. Please install package 'binutils' for better stacktrace output." );
            error = true;
        }
    #endif

    // If an error occured, exit now
    if( error ) {
        free( backtrace_strings );
        free( command_string );
        free( exe_path );
        return NULL;
    }

    for( int i = 0; i < array_size; i++ ) {
        // Compose the complete command to execute
        sprintf( command_string, "%s %s %X", command, exe_path, addresses[i] );

        // Execute the command
        FILE* line = popen( command_string, "r" );

        // Get the size of the command output
        int line_size = fseek( line, 0, SEEK_END );

        // Read the output into the return string
        fgets( backtrace_strings[i] , line_size, line );

        // Close the command pipe
        pclose( line );
    }

    return backtrace_strings;
}

返回的路径readlink()是:/home/nax��?第一部分是正确的:/home/na,但此后的所有内容都是胡言乱语。

为什么我无法以这种方式获取当前的执行路径?

胡安尔
char* exe_path          = (char*)malloc( 255 );
// ...
readlink( "/proc/self/exe", exe_path, sizeof( exe_path ) )

exe_path是一个指针,因此它的大小将等于sizeof(char *)(4或8),而不是255。

更改exe_pathchar[255]或更改为sizeof

顺便说一句,readlink不会追加NULL字节,因此您应该执行以下操作:

len = readlink( "/proc/self/exe", exe_path, sizeof( exe_path ) )
exe_path[len] = 0;

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

在 C++ 中使用 AssocQueryString 获取可执行路径

UWA C#获取XML文件的可执行路径

如何从.desktop文件中的可执行路径获取期望的进程名称

JavaScript执行路径

C#:如何获取给定无路径文件时Process.Start将使用的可执行路径?

Bash选项获取已解析的可执行路径?

如何在Python中获取当前执行文件的路径?

获取当前在Steel Bank Common Lisp中执行的脚本的路径

OS X的Java执行路径中的空格

如何在Mac中执行路径导出文件?

可执行路径必须在Python的PATH中

Bash:如何执行路径

为什么“ do”(红色语言本机功能)正在更改当前执行路径?

获取当前执行模块代码的文件路径

如何通过此pid执行的文件获取pid及其可执行路径信息?

如何在C#中获取当前用户的桌面路径?

如何在C ++中获取当前的源路径-Linux

无法获取.net core 3.0单个文件'/ p:PublishSingleFile = true'的原始可执行路径

.desktop文件。正确的执行路径

如何找到php的可执行路径?

Windows Update可执行路径

在C Shell中执行脚本时获取脚本路径

即使条件代码中的__syncthreads()位于“非活动”执行路径中,它也始终运行吗?

是否让淘汰赛计算对象订阅不在初始执行路径中的可观察对象?

如何对IIS中托管的此服务执行路径遍历攻击?

在 Rider IDE 中为 Web 项目更改运行/调试配置的可执行路径

SonarQube中至少一个执行路径上的“响应”为空

Java执行路径名称中带有空格的命令

在Kruskal算法的Java实现中,到底应该在哪里执行路径压缩?