예제 #1
0
파일: test_util.c 프로젝트: JacobStoren/ert
void test_util_addr2line() {
  const char * file = __FILE__;
  const char * func = __func__;
  int    line;
  const int max_bt = 50;
  void *bt_addr[max_bt];  
  int size;
  char * func_name , * file_name;
  int line_nr;
  
  line = __LINE__ + 2;
  size = backtrace(bt_addr , max_bt);    
  test_assert_int_equal( size , 4 );
  test_assert_true( util_addr2line_lookup( bt_addr[0] , &func_name , &file_name , &line_nr));
  test_assert_string_equal( func_name , func );
  test_assert_int_equal( line , line_nr );
  test_assert_string_equal( file_name , file );
}
예제 #2
0
void util_abort(const char * fmt , ...) {
  pthread_mutex_lock( &__abort_mutex ); /* Abort before unlock() */
  {
    va_list ap;

    va_start(ap , fmt);
    printf("\n\n");
    fprintf(stderr,"\n\n");
    vfprintf(stderr , fmt , ap);
    va_end(ap);

    /*
      The backtrace is based on calling the external program
      addr2line; the call is based on util_fork_exec() which is
      currently only available on POSIX.
    */

    const bool include_backtrace = true;
    if (include_backtrace) {
      const int max_bt = 50;
      char *executable;
      void *array[max_bt];
      char **strings;
      char ** func_list;
      char ** file_line_list;
      int    max_func_length = 0;
      int    size,i;
  
      if (__abort_program_message != NULL) {
        fprintf(stderr,"--------------------------------------------------------------------------------\n");
        fprintf(stderr,"%s",__abort_program_message);
        fprintf(stderr,"--------------------------------------------------------------------------------\n");
      }

      fprintf(stderr,"\n");
      fprintf(stderr,"****************************************************************************\n");
      fprintf(stderr,"**                                                                        **\n");
      fprintf(stderr,"**           A fatal error occured, and we have to abort.                 **\n");
      fprintf(stderr,"**                                                                        **\n");
      fprintf(stderr,"**  We now *try* to provide a backtrace, which would be very useful       **\n");
      fprintf(stderr,"**  when debugging. The process of making a (human readable) backtrace    **\n");
      fprintf(stderr,"**  is quite complex, among other things it involves several calls to the **\n");
      fprintf(stderr,"**  external program addr2line. We have arrived here because the program  **\n");
      fprintf(stderr,"**  state is already quite broken, so the backtrace might be (seriously)  **\n");
      fprintf(stderr,"**  broken as well.                                                       **\n");
      fprintf(stderr,"**                                                                        **\n");
      fprintf(stderr,"****************************************************************************\n");
      size       = backtrace(array , max_bt);
      strings    = backtrace_symbols(array , size);    
      executable = util_bt_alloc_current_executable(strings[0]);
      if (executable != NULL) {
        fprintf(stderr,"Current executable : %s \n",executable);
        
        func_list      = util_calloc(size , sizeof * func_list      );
        file_line_list = util_calloc(size , sizeof * file_line_list );
        
        for (i=0; i < size; i++) {
          util_addr2line_lookup(executable , strings[i] , &func_list[i] , &file_line_list[i]);
          max_func_length = util_int_max(max_func_length , strlen(func_list[i]));
        }
        
        {
          char string_fmt[64];
          sprintf(string_fmt, " #%s02d %s-%ds(..) in %ss   \n" , "%" , "%" , max_func_length , "%");
          fprintf(stderr , "--------------------------------------------------------------------------------\n");
          for (i=0; i < size; i++) {
            
            int line_nr;
            if (util_sscanf_int(file_line_list[i] , &line_nr))
              fprintf(stderr, string_fmt , i , func_list[i], file_line_list[i]);
            else
              fprintf(stderr, string_fmt , i , func_list[i], file_line_list[i]);
          }
          fprintf(stderr , "--------------------------------------------------------------------------------\n");
          util_free_stringlist(func_list      , size);
          util_free_stringlist(file_line_list , size);
        }
      } else
        fprintf(stderr,"Could not determine executable file for:%s - no backtrace. \n",strings[0]);
      
      free(strings);
      util_safe_free(executable);
    }

    if (getenv("UTIL_ABORT") != NULL) {
      fprintf(stderr , "Aborting ... \n");
      abort();
    } else {
      fprintf(stderr , "Exiting ... \n");
      exit(1);
    }
    // Would have preferred abort() here - but that comes in conflict with the SIGABRT signal.
  }
  pthread_mutex_unlock( &__abort_mutex );
}