SlideShare ist ein Scribd-Unternehmen logo
1 von 14
Hooking the signals and dumping the  backtraces Thierry GAYET
GOAL  The main goal of this document is to provide some information about the signal handling used for dumping the bacltrace due after a crash.
A backtrace is a list of the function calls that are currently active in a thread. The usual way to inspect a backtrace of a program is to use an external debugger such as gdb. H owever, sometimes it is useful to obtain a backtrace programmatically from within a program, e.g., for the purposes of logging or diagnostics. The header file `execinfo.h' declares three functions that obtain and manipulate backtraces of the current thread.    Function: int backtrace(void **buffer, int size) The backtrace function obtains a backtrace for the current thread, as a list of pointers, and places the information into buffer. The argument size should be the number of void * elements that will fit into buffer. The return value is the actual number of entries of buffer that are obtained, and is at most size. The pointers placed in buffer are actually return addresses obtained by inspecting the stack, one return address per stack frame. Note that certain compiler optimizations may interfere with obtaining a valid backtrace. Function inlining causes the inlined function to not have a stack frame; tail call optimization replaces one stack frame with another; frame pointer elimination will stop backtrace from interpreting the stack contents correctly. Usage
   Function: char ** backtrace_symbols (void *const *buffer, int size) The backtrace_symbols function translates the information obtained from the backtrace function into an array of strings. The argument buffer should be a pointer to an array of addresses obtained via the backtrace function, and size is the number of entries in that array (the return value of backtrace). The return value is a pointer to an array of strings, which has size entries just like the array buffer. Each string contains a printable representation of the corresponding element of buffer. It includes the function name (if this can be determined), an offset into the function, and the actual return address (in hexadecimal). Currently, the function name and offset only be obtained on systems that use the ELF binary format for programs and libraries. On other systems, only the hexadecimal return address will be present. Also, you may need to pass additional flags to the linker to make the function names available to the program. (For example, on systems using GNU ld, you must pass (-rdynamic.) The return value of backtrace_symbols is a pointer obtained via the malloc function, and it is the responsibility of the caller to free that pointer. Note that only the return value need be freed, not the individual strings. The return value is NULL if sufficient memory for the strings cannot be obtained. Usage
   Function: void backtrace_symbols_fd (void *const *buffer, int size, int fd) The backtrace_symbols_fd function performs the same translation as the function backtrace_symbols function. Instead of returning the strings to the caller, it writes the strings to the file descriptor fd, one per line.  It does not use the malloc function, and can therefore be used in situations where that function might fail. The following program illustrates the use of these functions. Note that the array to contain the return addresses returned by backtrace is allocated on the stack.  Therefore code like this can be used in situations where the memory handling via malloc does not work anymore (in which case the backtrace_symbols has to be replaced by a backtrace_symbols_fd call as well).  The number of return addresses is normally not very large. Even complicated programs rather seldom have a nesting level of more than, say, 50 and with 200 possible entries probably all programs should be covered. Usage
#include <execinfo.h> #include <stdio.h> #include <stdlib.h> /* Obtain a backtrace and print it to stdout. */ void print_trace(void) {   void*  array[10]; size_t size; char** strings; size_t i; size  = backtrace(array, 10); strings = backtrace_symbols(array, size); printf (&quot;Obtained %zd stack frames.&quot;, size); for (i = 0; i < size; i++) { printf (&quot;%s&quot;, strings[i]); } /* FOR */ free (strings); } /* print_trace */ /* A dummy function to make the backtrace more interesting. */ void dummy_function(void) { print_trace(); } /* dummy_function */ Int  main(void) { dummy_function (); return 0; } First example
#include <stdio.h> #include <stdlib.h> #include <signal.h> #include <unistd.h> #include <sys/times.h> #include <sys/ucontext.h> #include <asm/unistd.h> #include <execinfo.h> struct dict_entry { int num; const char *s; }; #define DICT_ENTRY_END { -1, NULL } #define PRINTF(fmt...) fprintf(stderr,fmt); static int mainpid=0; /* * Simple dictionary * Search an array terminated by an entry with s field set to NULL * If number not found, return &quot;(unknown)&quot; string */ static const char * search_dict(const struct dict_entry *dict, int num) { const struct dict_entry *p = dict; while (p->s) { if (num == p->num) return p->s; p++; } return &quot;(unknown)&quot;; } Second example 1/6
static const struct dict_entry sig_names[] =  { {SIGHUP, &quot;SIGHUP&quot;}, {SIGINT, &quot;SIGINT&quot;}, {SIGQUIT, &quot;SIGQUIT&quot;}, {SIGILL, &quot;SIGILL&quot;}, {SIGTRAP, &quot;SIGTRAP&quot;}, {SIGABRT, &quot;SIGABRT&quot;}, {SIGBUS, &quot;SIGBUS&quot;}, {SIGFPE, &quot;SIGFPE&quot;}, {SIGKILL, &quot;SIGKILL&quot;}, {SIGSEGV, &quot;SIGSEGV&quot;}, {SIGPIPE, &quot;SIGPIPE&quot;}, {SIGALRM, &quot;SIGALRM&quot;}, {SIGTERM, &quot;SIGTERM&quot;}, {SIGSTKFLT, &quot;SIGSTKFLT&quot;}, {SIGCHLD, &quot;SIGCHLD&quot;}, {SIGCONT, &quot;SIGCONT&quot;}, {SIGSTOP, &quot;SIGSTOP&quot;}, {SIGTSTP, &quot;SIGTSTP&quot;}, {SIGTTIN, &quot;SIGTTIN&quot;}, {SIGTTOU, &quot;SIGTTOU&quot;}, {SIGURG, &quot;SIGURG&quot;}, {SIGXCPU, &quot;SIGXCPU&quot;}, {SIGXFSZ, &quot;SIGXFSZ&quot;}, {SIGVTALRM, &quot;SIGVTALRM&quot;}, {SIGPROF, &quot;SIGPROF&quot;}, {SIGWINCH, &quot;SIGWINCH&quot;}, {SIGPOLL, &quot;SIGPOLL&quot;}, {SIGPWR, &quot;SIGPWR&quot;}, {SIGSYS, &quot;SIGSYS&quot;}, DICT_ENTRY_END }; Second example 2/6
static void show_stack() { void *trace[16]; char **messages = (char **)NULL; int i, trace_size = 0; trace_size = backtrace(trace, 16); /* overwrite sigaction with caller's address */ messages = backtrace_symbols(trace, trace_size); /* skip first stack frame (points here) */ printf(&quot;CALLSTACK:&quot;); for (i=1; i<trace_size; ++i) printf(&quot;%s&quot;, messages[i]); free (messages); } Second example 3/6
Second example 4/6 void sigdemux(int sig, struct siginfo *si, void *v) { const char *signame; //struct ucontext *sc=(struct ucontext *)v; //struct sigcontext *regs; int si_code; si_code = si->si_code & 0xffff;  signame = search_dict(sig_names, sig); if (sig != SIGINT)  { PRINTF(&quot;!==========================!&quot;); PRINTF(&quot;SIG %s (#%i) received in PID %ld&quot;,signame,sig,syscall(__NR_gettid)); PRINTF(&quot;Errno%iPID%iaddr0x%08x&quot;, (int)si->si_errno, (int)si->si_pid, (int)si->si_addr); show_stack(); PRINTF(&quot;!==========================!&quot;); kill(mainpid,SIGINT); exit(-1); } if (getpid()==mainpid)  { exit(0); } return; }
Second example 5/6 int sig_init(int pid) { struct sigaction si_segv; int rc; si_segv.sa_sigaction = sigdemux; si_segv.sa_flags = SA_SIGINFO; mainpid=pid; rc = sigaction(SIGINT,&si_segv,NULL); if (rc<0) { goto sig_error; } rc = sigaction(SIGSEGV,&si_segv,NULL); if (rc<0) { goto sig_error; } rc = sigaction(SIGILL,&si_segv,NULL); if (rc<0) { goto sig_error; } rc = sigaction(SIGFPE,&si_segv,NULL); if (rc<0) { goto sig_error; } rc = sigaction(SIGBUS,&si_segv,NULL); if (rc<0) { goto sig_error; } rc = sigaction(SIGPIPE,&si_segv,NULL); if (rc<0) { goto sig_error; } sig_error: return rc; }
[object Object],[object Object],[object Object],[object Object],[object Object],Usage of the second source code (6/6)
[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],Result
More help ,[object Object]

Weitere ähnliche Inhalte

Was ist angesagt?

Lecturer23 pointersin c.ppt
Lecturer23 pointersin c.pptLecturer23 pointersin c.ppt
Lecturer23 pointersin c.ppt
eShikshak
 

Was ist angesagt? (20)

Pointers in C
Pointers in CPointers in C
Pointers in C
 
Pointers in C/C++ Programming
Pointers in C/C++ ProgrammingPointers in C/C++ Programming
Pointers in C/C++ Programming
 
Pointers+(2)
Pointers+(2)Pointers+(2)
Pointers+(2)
 
Types of pointer in C
Types of pointer in CTypes of pointer in C
Types of pointer in C
 
Pointers
PointersPointers
Pointers
 
Lecturer23 pointersin c.ppt
Lecturer23 pointersin c.pptLecturer23 pointersin c.ppt
Lecturer23 pointersin c.ppt
 
Module 02 Pointers in C
Module 02 Pointers in CModule 02 Pointers in C
Module 02 Pointers in C
 
Pointers_c
Pointers_cPointers_c
Pointers_c
 
01 stack 20160908_jintaek_seo
01 stack 20160908_jintaek_seo01 stack 20160908_jintaek_seo
01 stack 20160908_jintaek_seo
 
C pointer basics
C pointer basicsC pointer basics
C pointer basics
 
C for Java programmers (part 2)
C for Java programmers (part 2)C for Java programmers (part 2)
C for Java programmers (part 2)
 
C for Java programmers (part 1)
C for Java programmers (part 1)C for Java programmers (part 1)
C for Java programmers (part 1)
 
Pointer in c program
Pointer in c programPointer in c program
Pointer in c program
 
Pointer in C
Pointer in CPointer in C
Pointer in C
 
C for Java programmers (part 3)
C for Java programmers (part 3)C for Java programmers (part 3)
C for Java programmers (part 3)
 
C
CC
C
 
Csdfsadf
CsdfsadfCsdfsadf
Csdfsadf
 
C pointers
C pointersC pointers
C pointers
 
Pointers in C Language
Pointers in C LanguagePointers in C Language
Pointers in C Language
 
Used of Pointer in C++ Programming
Used of Pointer in C++ ProgrammingUsed of Pointer in C++ Programming
Used of Pointer in C++ Programming
 

Andere mochten auch

Bluetooth on GNU Linux
Bluetooth on GNU LinuxBluetooth on GNU Linux
Bluetooth on GNU Linux
Thierry Gayet
 
Utilisation d'un système de tag des objets elf
Utilisation d'un système de tag des objets elfUtilisation d'un système de tag des objets elf
Utilisation d'un système de tag des objets elf
Thierry Gayet
 
Intro to the raspberry pi board
Intro to the raspberry pi boardIntro to the raspberry pi board
Intro to the raspberry pi board
Thierry Gayet
 
Etude DéTailléé de la pile réseau sous GNU Linux
Etude DéTailléé de la pile réseau sous GNU LinuxEtude DéTailléé de la pile réseau sous GNU Linux
Etude DéTailléé de la pile réseau sous GNU Linux
Thierry Gayet
 
Rappels de développements sous GNU Linux
Rappels de développements sous GNU LinuxRappels de développements sous GNU Linux
Rappels de développements sous GNU Linux
Thierry Gayet
 
Développement Noyau Et Driver Sous Gnu Linux
Développement Noyau Et Driver Sous Gnu LinuxDéveloppement Noyau Et Driver Sous Gnu Linux
Développement Noyau Et Driver Sous Gnu Linux
Thierry Gayet
 

Andere mochten auch (20)

Google mock training
Google mock trainingGoogle mock training
Google mock training
 
Working with core dump
Working with core dumpWorking with core dump
Working with core dump
 
Bluetooth on GNU Linux
Bluetooth on GNU LinuxBluetooth on GNU Linux
Bluetooth on GNU Linux
 
Formation python
Formation pythonFormation python
Formation python
 
Comprendre les scripts shell auto-extractible
Comprendre les scripts shell auto-extractibleComprendre les scripts shell auto-extractible
Comprendre les scripts shell auto-extractible
 
Présentation de la pile réseau sous gnu linux
Présentation de la pile réseau sous gnu linuxPrésentation de la pile réseau sous gnu linux
Présentation de la pile réseau sous gnu linux
 
Utilisation d'un système de tag des objets elf
Utilisation d'un système de tag des objets elfUtilisation d'un système de tag des objets elf
Utilisation d'un système de tag des objets elf
 
Autotools pratical training
Autotools pratical trainingAutotools pratical training
Autotools pratical training
 
Intro to the raspberry pi board
Intro to the raspberry pi boardIntro to the raspberry pi board
Intro to the raspberry pi board
 
utilisation des core dump sous linux
utilisation des core dump sous linuxutilisation des core dump sous linux
utilisation des core dump sous linux
 
Formation html3 css3
Formation html3 css3Formation html3 css3
Formation html3 css3
 
A la découverte d'abus
A la découverte d'abusA la découverte d'abus
A la découverte d'abus
 
Anatomie d'une des particularité de la libc
Anatomie d'une des particularité de la libcAnatomie d'une des particularité de la libc
Anatomie d'une des particularité de la libc
 
Compilation noyau linux depuis les sources
Compilation noyau linux depuis les sourcesCompilation noyau linux depuis les sources
Compilation noyau linux depuis les sources
 
A la découverte de redo
A la découverte de redoA la découverte de redo
A la découverte de redo
 
Etude DéTailléé de la pile réseau sous GNU Linux
Etude DéTailléé de la pile réseau sous GNU LinuxEtude DéTailléé de la pile réseau sous GNU Linux
Etude DéTailléé de la pile réseau sous GNU Linux
 
Rappels de développements sous GNU Linux
Rappels de développements sous GNU LinuxRappels de développements sous GNU Linux
Rappels de développements sous GNU Linux
 
Ecriture de classes javascript
Ecriture de classes javascriptEcriture de classes javascript
Ecriture de classes javascript
 
From gcc to the autotools
From gcc to the autotoolsFrom gcc to the autotools
From gcc to the autotools
 
Développement Noyau Et Driver Sous Gnu Linux
Développement Noyau Et Driver Sous Gnu LinuxDéveloppement Noyau Et Driver Sous Gnu Linux
Développement Noyau Et Driver Sous Gnu Linux
 

Ähnlich wie Hooking signals and dumping the callstack

Unit 4
Unit 4Unit 4
Unit 4
siddr
 
Input output functions
Input output functionsInput output functions
Input output functions
hyderali123
 
C,c++ interview q&a
C,c++ interview q&aC,c++ interview q&a
C,c++ interview q&a
Kumaran K
 
Buffer overflow tutorial
Buffer overflow tutorialBuffer overflow tutorial
Buffer overflow tutorial
hughpearse
 
Q1 Consider the below omp_trap1.c implantation, modify the code so t.pdf
Q1 Consider the below omp_trap1.c implantation, modify the code so t.pdfQ1 Consider the below omp_trap1.c implantation, modify the code so t.pdf
Q1 Consider the below omp_trap1.c implantation, modify the code so t.pdf
abdulrahamanbags
 

Ähnlich wie Hooking signals and dumping the callstack (20)

Unit 4
Unit 4Unit 4
Unit 4
 
C programming language tutorial
C programming language tutorial C programming language tutorial
C programming language tutorial
 
C programming(part 3)
C programming(part 3)C programming(part 3)
C programming(part 3)
 
Quiz 9
Quiz 9Quiz 9
Quiz 9
 
Input output functions
Input output functionsInput output functions
Input output functions
 
08 -functions
08  -functions08  -functions
08 -functions
 
Clean code _v2003
 Clean code _v2003 Clean code _v2003
Clean code _v2003
 
Rpg Pointers And User Space
Rpg Pointers And User SpaceRpg Pointers And User Space
Rpg Pointers And User Space
 
C,c++ interview q&a
C,c++ interview q&aC,c++ interview q&a
C,c++ interview q&a
 
Functions
FunctionsFunctions
Functions
 
Python scripting kick off
Python scripting kick offPython scripting kick off
Python scripting kick off
 
Buffer overflow tutorial
Buffer overflow tutorialBuffer overflow tutorial
Buffer overflow tutorial
 
The Ring programming language version 1.10 book - Part 97 of 212
The Ring programming language version 1.10 book - Part 97 of 212The Ring programming language version 1.10 book - Part 97 of 212
The Ring programming language version 1.10 book - Part 97 of 212
 
Q1 Consider the below omp_trap1.c implantation, modify the code so t.pdf
Q1 Consider the below omp_trap1.c implantation, modify the code so t.pdfQ1 Consider the below omp_trap1.c implantation, modify the code so t.pdf
Q1 Consider the below omp_trap1.c implantation, modify the code so t.pdf
 
Assignment c programming
Assignment c programmingAssignment c programming
Assignment c programming
 
C programming
C programmingC programming
C programming
 
C
CC
C
 
Best C++ Programming Homework Help
Best C++ Programming Homework HelpBest C++ Programming Homework Help
Best C++ Programming Homework Help
 
programming language in c&c++
programming language in c&c++programming language in c&c++
programming language in c&c++
 
88 c-programs
88 c-programs88 c-programs
88 c-programs
 

Kürzlich hochgeladen

Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
panagenda
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
WSO2
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 

Kürzlich hochgeladen (20)

Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with Milvus
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
 
Vector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxVector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptx
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 

Hooking signals and dumping the callstack

  • 1. Hooking the signals and dumping the backtraces Thierry GAYET
  • 2. GOAL  The main goal of this document is to provide some information about the signal handling used for dumping the bacltrace due after a crash.
  • 3. A backtrace is a list of the function calls that are currently active in a thread. The usual way to inspect a backtrace of a program is to use an external debugger such as gdb. H owever, sometimes it is useful to obtain a backtrace programmatically from within a program, e.g., for the purposes of logging or diagnostics. The header file `execinfo.h' declares three functions that obtain and manipulate backtraces of the current thread.  Function: int backtrace(void **buffer, int size) The backtrace function obtains a backtrace for the current thread, as a list of pointers, and places the information into buffer. The argument size should be the number of void * elements that will fit into buffer. The return value is the actual number of entries of buffer that are obtained, and is at most size. The pointers placed in buffer are actually return addresses obtained by inspecting the stack, one return address per stack frame. Note that certain compiler optimizations may interfere with obtaining a valid backtrace. Function inlining causes the inlined function to not have a stack frame; tail call optimization replaces one stack frame with another; frame pointer elimination will stop backtrace from interpreting the stack contents correctly. Usage
  • 4. Function: char ** backtrace_symbols (void *const *buffer, int size) The backtrace_symbols function translates the information obtained from the backtrace function into an array of strings. The argument buffer should be a pointer to an array of addresses obtained via the backtrace function, and size is the number of entries in that array (the return value of backtrace). The return value is a pointer to an array of strings, which has size entries just like the array buffer. Each string contains a printable representation of the corresponding element of buffer. It includes the function name (if this can be determined), an offset into the function, and the actual return address (in hexadecimal). Currently, the function name and offset only be obtained on systems that use the ELF binary format for programs and libraries. On other systems, only the hexadecimal return address will be present. Also, you may need to pass additional flags to the linker to make the function names available to the program. (For example, on systems using GNU ld, you must pass (-rdynamic.) The return value of backtrace_symbols is a pointer obtained via the malloc function, and it is the responsibility of the caller to free that pointer. Note that only the return value need be freed, not the individual strings. The return value is NULL if sufficient memory for the strings cannot be obtained. Usage
  • 5. Function: void backtrace_symbols_fd (void *const *buffer, int size, int fd) The backtrace_symbols_fd function performs the same translation as the function backtrace_symbols function. Instead of returning the strings to the caller, it writes the strings to the file descriptor fd, one per line. It does not use the malloc function, and can therefore be used in situations where that function might fail. The following program illustrates the use of these functions. Note that the array to contain the return addresses returned by backtrace is allocated on the stack. Therefore code like this can be used in situations where the memory handling via malloc does not work anymore (in which case the backtrace_symbols has to be replaced by a backtrace_symbols_fd call as well). The number of return addresses is normally not very large. Even complicated programs rather seldom have a nesting level of more than, say, 50 and with 200 possible entries probably all programs should be covered. Usage
  • 6. #include <execinfo.h> #include <stdio.h> #include <stdlib.h> /* Obtain a backtrace and print it to stdout. */ void print_trace(void) { void* array[10]; size_t size; char** strings; size_t i; size = backtrace(array, 10); strings = backtrace_symbols(array, size); printf (&quot;Obtained %zd stack frames.&quot;, size); for (i = 0; i < size; i++) { printf (&quot;%s&quot;, strings[i]); } /* FOR */ free (strings); } /* print_trace */ /* A dummy function to make the backtrace more interesting. */ void dummy_function(void) { print_trace(); } /* dummy_function */ Int main(void) { dummy_function (); return 0; } First example
  • 7. #include <stdio.h> #include <stdlib.h> #include <signal.h> #include <unistd.h> #include <sys/times.h> #include <sys/ucontext.h> #include <asm/unistd.h> #include <execinfo.h> struct dict_entry { int num; const char *s; }; #define DICT_ENTRY_END { -1, NULL } #define PRINTF(fmt...) fprintf(stderr,fmt); static int mainpid=0; /* * Simple dictionary * Search an array terminated by an entry with s field set to NULL * If number not found, return &quot;(unknown)&quot; string */ static const char * search_dict(const struct dict_entry *dict, int num) { const struct dict_entry *p = dict; while (p->s) { if (num == p->num) return p->s; p++; } return &quot;(unknown)&quot;; } Second example 1/6
  • 8. static const struct dict_entry sig_names[] = { {SIGHUP, &quot;SIGHUP&quot;}, {SIGINT, &quot;SIGINT&quot;}, {SIGQUIT, &quot;SIGQUIT&quot;}, {SIGILL, &quot;SIGILL&quot;}, {SIGTRAP, &quot;SIGTRAP&quot;}, {SIGABRT, &quot;SIGABRT&quot;}, {SIGBUS, &quot;SIGBUS&quot;}, {SIGFPE, &quot;SIGFPE&quot;}, {SIGKILL, &quot;SIGKILL&quot;}, {SIGSEGV, &quot;SIGSEGV&quot;}, {SIGPIPE, &quot;SIGPIPE&quot;}, {SIGALRM, &quot;SIGALRM&quot;}, {SIGTERM, &quot;SIGTERM&quot;}, {SIGSTKFLT, &quot;SIGSTKFLT&quot;}, {SIGCHLD, &quot;SIGCHLD&quot;}, {SIGCONT, &quot;SIGCONT&quot;}, {SIGSTOP, &quot;SIGSTOP&quot;}, {SIGTSTP, &quot;SIGTSTP&quot;}, {SIGTTIN, &quot;SIGTTIN&quot;}, {SIGTTOU, &quot;SIGTTOU&quot;}, {SIGURG, &quot;SIGURG&quot;}, {SIGXCPU, &quot;SIGXCPU&quot;}, {SIGXFSZ, &quot;SIGXFSZ&quot;}, {SIGVTALRM, &quot;SIGVTALRM&quot;}, {SIGPROF, &quot;SIGPROF&quot;}, {SIGWINCH, &quot;SIGWINCH&quot;}, {SIGPOLL, &quot;SIGPOLL&quot;}, {SIGPWR, &quot;SIGPWR&quot;}, {SIGSYS, &quot;SIGSYS&quot;}, DICT_ENTRY_END }; Second example 2/6
  • 9. static void show_stack() { void *trace[16]; char **messages = (char **)NULL; int i, trace_size = 0; trace_size = backtrace(trace, 16); /* overwrite sigaction with caller's address */ messages = backtrace_symbols(trace, trace_size); /* skip first stack frame (points here) */ printf(&quot;CALLSTACK:&quot;); for (i=1; i<trace_size; ++i) printf(&quot;%s&quot;, messages[i]); free (messages); } Second example 3/6
  • 10. Second example 4/6 void sigdemux(int sig, struct siginfo *si, void *v) { const char *signame; //struct ucontext *sc=(struct ucontext *)v; //struct sigcontext *regs; int si_code; si_code = si->si_code & 0xffff; signame = search_dict(sig_names, sig); if (sig != SIGINT) { PRINTF(&quot;!==========================!&quot;); PRINTF(&quot;SIG %s (#%i) received in PID %ld&quot;,signame,sig,syscall(__NR_gettid)); PRINTF(&quot;Errno%iPID%iaddr0x%08x&quot;, (int)si->si_errno, (int)si->si_pid, (int)si->si_addr); show_stack(); PRINTF(&quot;!==========================!&quot;); kill(mainpid,SIGINT); exit(-1); } if (getpid()==mainpid) { exit(0); } return; }
  • 11. Second example 5/6 int sig_init(int pid) { struct sigaction si_segv; int rc; si_segv.sa_sigaction = sigdemux; si_segv.sa_flags = SA_SIGINFO; mainpid=pid; rc = sigaction(SIGINT,&si_segv,NULL); if (rc<0) { goto sig_error; } rc = sigaction(SIGSEGV,&si_segv,NULL); if (rc<0) { goto sig_error; } rc = sigaction(SIGILL,&si_segv,NULL); if (rc<0) { goto sig_error; } rc = sigaction(SIGFPE,&si_segv,NULL); if (rc<0) { goto sig_error; } rc = sigaction(SIGBUS,&si_segv,NULL); if (rc<0) { goto sig_error; } rc = sigaction(SIGPIPE,&si_segv,NULL); if (rc<0) { goto sig_error; } sig_error: return rc; }
  • 12.
  • 13.
  • 14.