문제

저는 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는 포인터이므로 크기는 255가 아닌 sizeof(char*)(4 또는 8)와 같습니다.

변화 exe_path 에게 char[255] 또는 통화를 다음으로 변경하세요. sizeof

그런데 readlink는 NULL 바이트를 추가하지 않으므로 다음과 같이 해야 합니다:

len = readlink( "/proc/self/exe", exe_path, sizeof( exe_path ) )
exe_path[len] = 0;
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top