Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* ** This is a test of a concept I found here:
- http://blog.bigpixel.ro/2010/09/09/stack-unwinding-stack-trace-with-gcc/
- ... regarding the production of a stacktrace
- from GCC on various error conditions.
- I'll be damned if it doesn't work, too.
- ** */
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include <signal.h>
- #include <libunwind.h>
- #include <libunwind-x86.h>
- int getFileAndLine (unw_word_t addr, char *file, size_t flen, int *line)
- {
- static char buf[256];
- char *p;
- // prepare command to be executed
- // our program need to be passed after the -e parameter
- sprintf (buf, "/usr/bin/addr2line -C -e ./test -f -i %lx", (unsigned long) addr);
- FILE* f = popen (buf, "r");
- if (f == NULL)
- {
- perror (buf);
- return 0;
- }
- // get function name
- fgets (buf, 256, f);
- // get file and line
- fgets (buf, 256, f);
- if (buf[0] != '?')
- {
- int l;
- char *p = buf;
- // file name is until ':'
- while (*p != ':')
- {
- p++;
- }
- *p++ = 0;
- // after file name follows line number
- strcpy (file , buf);
- sscanf (p,"%d", line);
- }
- else
- {
- strcpy (file,"unkown");
- *line = 0;
- }
- pclose(f);
- }
- void show_backtrace (void)
- {
- char name[256];
- unw_cursor_t cursor; unw_context_t uc;
- unw_word_t ip, sp, offp;
- unw_getcontext(&uc);
- unw_init_local(&cursor, &uc);
- while (unw_step(&cursor) > 0)
- {
- char file[256];
- int line = 0;
- name[0] = '\0';
- unw_get_proc_name(&cursor, name, 256, &offp);
- unw_get_reg(&cursor, UNW_REG_IP, &ip);
- unw_get_reg(&cursor, UNW_REG_SP, &sp);
- //printf ("%s ip = %lx, sp = %lx\n", name, (long) ip, (long) sp);
- getFileAndLine((long)ip, file, 256, &line);
- printf("%s in file %s line %d\n", name, file, line);
- }
- }
- volatile sig_atomic_t fatal_error_in_progress = 0;
- void fatal_error_signal (int sig)
- {
- /* Since this handler is established for more than one kind of signal,
- it might still get invoked recursively by delivery of some other kind
- of signal. Use a static variable to keep track of that. */
- if (fatal_error_in_progress)
- raise (sig);
- fatal_error_in_progress = 1;
- show_backtrace();
- signal (sig, SIG_DFL);
- raise (sig);
- }
- void ReallyBreakIt()
- {
- char *ptr = NULL;
- char x = 0x0;
- printf("About to break the universe!\n");
- x = *(ptr);
- }
- void breakForReal()
- {
- ReallyBreakIt();
- }
- void breakTheUniverse()
- {
- breakForReal();
- }
- int main(void)
- {
- signal(SIGSEGV, &fatal_error_signal);
- breakTheUniverse();
- return 0;
- }
- /****** THIS IS THE OUTPUT *******
- About to break the universe!
- fatal_error_signal in file /home/akesterson/source/test.c line 93
- in file unkown line 0
- ReallyBreakIt in file /home/akesterson/source/test.c line 102
- breakForReal in file /home/akesterson/source/test.c line 108
- breakTheUniverse in file /home/akesterson/source/test.c line 113
- main in file /home/akesterson/source/test.c line 119
- __libc_start_main in file unkown line 0
- _start in file unkown line 0
- Segmentation fault
- ********/
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement