Advertisement
Guest User

Untitled

a guest
Sep 9th, 2010
1,195
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.03 KB | None | 0 0
  1. /* ** This is a test of a concept I found here:
  2.  
  3. http://blog.bigpixel.ro/2010/09/09/stack-unwinding-stack-trace-with-gcc/
  4.  
  5.     ... regarding the production of a stacktrace
  6. from GCC on various error conditions.
  7.  
  8.     I'll be damned if it doesn't work, too.
  9. ** */
  10.  
  11. #include <stdio.h>
  12. #include <string.h>
  13. #include <stdlib.h>
  14. #include <signal.h>
  15. #include <libunwind.h>
  16. #include <libunwind-x86.h>
  17.  
  18. int getFileAndLine (unw_word_t addr, char *file, size_t flen, int *line)
  19. {
  20.     static char buf[256];
  21.     char *p;
  22.  
  23.     // prepare command to be executed
  24.     // our program need to be passed after the -e parameter
  25.     sprintf (buf, "/usr/bin/addr2line -C -e ./test -f -i %lx", (unsigned long) addr);
  26.     FILE* f = popen (buf, "r");
  27.  
  28.     if (f == NULL)
  29.     {
  30.         perror (buf);
  31.         return 0;
  32.     }
  33.  
  34.     // get function name
  35.     fgets (buf, 256, f);
  36.  
  37.     // get file and line
  38.     fgets (buf, 256, f);
  39.  
  40.     if (buf[0] != '?')
  41.     {
  42.         int l;
  43.         char *p = buf;
  44.  
  45.         // file name is until ':'
  46.         while (*p != ':')
  47.         {
  48.             p++;
  49.         }
  50.  
  51.         *p++ = 0;
  52.         // after file name follows line number
  53.         strcpy (file , buf);
  54.         sscanf (p,"%d", line);
  55.     }
  56.     else
  57.     {
  58.         strcpy (file,"unkown");
  59.         *line = 0;
  60.     }
  61.  
  62.     pclose(f);
  63. }
  64.  
  65. void show_backtrace (void)
  66. {
  67.     char name[256];
  68.     unw_cursor_t cursor; unw_context_t uc;
  69.     unw_word_t ip, sp, offp;
  70.  
  71.     unw_getcontext(&uc);
  72.     unw_init_local(&cursor, &uc);
  73.  
  74.     while (unw_step(&cursor) > 0)
  75.     {
  76.         char file[256];
  77.         int line = 0;
  78.  
  79.         name[0] = '\0';
  80.         unw_get_proc_name(&cursor, name, 256, &offp);
  81.         unw_get_reg(&cursor, UNW_REG_IP, &ip);
  82.         unw_get_reg(&cursor, UNW_REG_SP, &sp);
  83.  
  84.         //printf ("%s ip = %lx, sp = %lx\n", name, (long) ip, (long) sp);
  85.         getFileAndLine((long)ip, file, 256, &line);
  86.         printf("%s in file %s line %d\n", name, file, line);
  87.     }
  88. }
  89.  
  90. volatile sig_atomic_t fatal_error_in_progress = 0;
  91.  
  92. void fatal_error_signal (int sig)
  93. {
  94.     /* Since this handler is established for more than one kind of signal,
  95.           it might still get invoked recursively by delivery of some other kind
  96.           of signal.  Use a static variable to keep track of that. */
  97.        if (fatal_error_in_progress)
  98.            raise (sig);
  99.        fatal_error_in_progress = 1;
  100.  
  101.     show_backtrace();
  102.  
  103.        signal (sig, SIG_DFL);
  104.        raise (sig);
  105. }
  106.  
  107. void ReallyBreakIt()
  108. {
  109.     char *ptr = NULL;
  110.     char x = 0x0;
  111.     printf("About to break the universe!\n");
  112.     x = *(ptr);
  113. }
  114.  
  115. void breakForReal()
  116. {
  117.     ReallyBreakIt();
  118. }
  119.  
  120. void breakTheUniverse()
  121. {
  122.     breakForReal();
  123. }
  124.  
  125. int main(void)
  126. {
  127.     signal(SIGSEGV, &fatal_error_signal);
  128.     breakTheUniverse();
  129.     return 0;
  130. }
  131.  
  132. /****** THIS IS THE OUTPUT *******
  133.  
  134. About to break the universe!
  135. fatal_error_signal in file /home/akesterson/source/test.c line 93
  136.  in file unkown line 0
  137. ReallyBreakIt in file /home/akesterson/source/test.c line 102
  138. breakForReal in file /home/akesterson/source/test.c line 108
  139. breakTheUniverse in file /home/akesterson/source/test.c line 113
  140. main in file /home/akesterson/source/test.c line 119
  141. __libc_start_main in file unkown line 0
  142. _start in file unkown line 0
  143. Segmentation fault
  144.  
  145. ********/
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement