Example #1
0
static bool util_addr2line_lookup__(const void * bt_addr , char ** func_name , char ** file_name , int * line_nr, bool subtract_base_adress) {
  *func_name = NULL;    // If dladdr() succeeds, but addr2line fails the func_name pointer will be set, but the function will return false anyway.
  *file_name = NULL;
  *line_nr   = 0;
  {
    bool  address_found = false;
    Dl_info dl_info;
#if defined(__APPLE__)
    return false;
#else
    if (dladdr(bt_addr , &dl_info)) {
      const char * executable = dl_info.dli_fname;
      *func_name = util_alloc_string_copy( dl_info.dli_sname );
      if (util_file_exists( executable )) {
        char *stdout_file = util_alloc_tmp_file("/tmp" , "addr2line" , true);
        /* 1: Run addr2line application */
        {
          char ** argv = util_calloc(3 , sizeof * argv );
          argv[0] = util_alloc_string_copy("--functions");
          argv[1] = util_alloc_sprintf("--exe=%s" , executable );
          {
            char * rel_address = (char *) bt_addr;
            if (subtract_base_adress)
              rel_address -= (size_t) dl_info.dli_fbase;
            argv[2] = util_alloc_sprintf("%p" , (void *) rel_address);
          }
          util_fork_exec("addr2line" , 3  , (const char **) argv , true , NULL , NULL , NULL , stdout_file , NULL);
          util_free_stringlist(argv , 3);
        }
        
        /* 2: Parse stdout output */
        {
          bool at_eof;
          FILE * stream = util_fopen(stdout_file , "r");
          char * tmp_fname = util_fscanf_alloc_line(stream , &at_eof);

          if (strcmp(tmp_fname , UNDEFINED_FUNCTION) != 0) {
            char * stdout_file_name = util_fscanf_alloc_line(stream , &at_eof);
            char * line_string = NULL;
            util_binary_split_string( stdout_file_name , ":" , false , file_name , &line_string);
            if (line_string && util_sscanf_int( line_string , line_nr)) 
              address_found = true;
            
            free( stdout_file_name );
            util_safe_free( line_string );
          }
          free( tmp_fname );
          fclose(stream);
        }
        util_unlink_existing(stdout_file);
        free( stdout_file );
      } 
    } 
    return address_found;
#endif
  }
}
Example #2
0
static void util_addr2line_lookup(const char * executable , const char * bt_symbol , char ** func_name , char ** file_line) {
  char *tmp_file = util_alloc_tmp_file("/tmp" , "addr2line" , true);
  char * adress;
  {
    int start_pos = 0;
    int end_pos;   
    while ( bt_symbol[start_pos] != '[')
      start_pos++;
    
      end_pos = start_pos;
      while ( bt_symbol[end_pos] != ']') 
        end_pos++;
      
      adress = util_alloc_substring_copy( bt_symbol , start_pos + 1 , end_pos - start_pos - 1 );
  }
  
  {
    char ** argv;
    
    argv    = util_calloc(3 , sizeof * argv );
    argv[0] = util_alloc_string_copy("--functions");
    argv[1] = util_alloc_sprintf("--exe=%s" , executable);
    argv[2] = util_alloc_string_copy(adress);
    
    util_fork_exec("addr2line" , 3  , (const char **) argv , true , NULL , NULL , NULL , tmp_file , NULL);
    util_free_stringlist(argv , 3);
  }
  
  {
    bool at_eof;
    FILE * stream = util_fopen(tmp_file , "r");
    *func_name = util_fscanf_alloc_line(stream , &at_eof);
    *file_line = util_fscanf_alloc_line(stream , &at_eof);
    fclose(stream);
  }
  util_unlink_existing(tmp_file);
  free(adress);
  free(tmp_file);
}