1. to free up some resource before the crash
2. to give a hint to the developer what happen - or even in production .
3. some exception i could catch even into catch(...)
the next code sample runs under linux , and compile with g++, i couldn't find an easy way to do it under windows (via VC++) as on linux , and in my case i need it under linux.
the idea is to register for any signal you want to handle , and in your function handler you need to write your cleaner, or print out the trace.
Do NOT FORGET in case of handler function you have to call to exit method , if you don't you will get into endless loop.
if you want to get the function name in your stack trace , ADD -rdynamic flag to your link settings.
here are some resources i used:
linux backtrace , generate a stacktrace
here is my sample test:
#include <iostream>
extern "C"
{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
}
#include <fstream>
#include <csignal>
#include <execinfo.h>
void PrintStack()
{
//backtrace_symbols_fd(array, size, 2);
// ADD -rdynamic flag to your link , to get method name and not hex address
void * array[25];
int nSize = backtrace(array, 25);
char ** symbols = backtrace_symbols(array, nSize);
for (int i = 0; i < nSize; i++)
{
printf("%s \n", symbols[i] );
}
if(symbols)
free(symbols);
}
void intrupt(int sig)
{
//..necessary cleanup operations before terminating
printf("handling signal no. %d - Interactive attention signal \n",sig);
PrintStack();
exit(sig);
}
void term(int sig)
{
//..necessary cleanup operations before terminating
printf("handling signal no. %d - Termination request made to the program \n",sig);
exit(sig);
}
void abort(int sig)
{
//..necessary cleanup operations before terminating
// cout << "handling signal no." << sig << endl << "Abnormal termination" << endl;
printf("handling signal no. %d - Abnormal termination \n",sig);
exit(sig);
}
void floatingPoint(int sig)
{
//..necessary cleanup operations before terminating
printf("handling signal no. %d - Abnormal termination floatingPoint \n",sig);
PrintStack();
exit(sig);
}
void IllegalInstruction(int sig)
{
//..necessary cleanup operations before terminating
printf("handling signal no. %d - Abnormal termination IllegalInstruction \n",sig);
exit(sig);
}
void IllegalStorage(int sig)
{
//..necessary cleanup operations before terminating
printf("handling signal no. %d - Abnormal termination IllegalStorage \n",sig);
PrintStack();
// no log when there is no exit here on aix ,
//on linux its in recursion so you have to call exit
exit(sig);
}
void foo()
{
int arrInt[4] = {1,2,3,4};
for(int i = 0 ; i < 2000;i++)
{
printf(" iRet index = %d , val= %d ........... ...\n",i,arrInt[i]);
}
}
void foo3()
{
char* data = 0 ;
int iRet = strlen(data);
printf(" strlen(data) = %d ........... ...\n",iRet);
strcpy(data, "hellozadsfaddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd");
printf(" dataLinux = %s ........... ...\n",data);
}
void foo2()
{
foo3();
}
class Crash
{
public:
void fooArrayOutOfIndex()
{
int arrInt[4] = {1,2,3,4};
for(int i = 0 ; i < 2000;i++)
{
printf(" iRet index = %d , val= %d ........... ...\n",i,arrInt[i]);
}
};
void foo3()
{
char* data = 0 ;
int iRet = strlen(data);
printf(" strlen(data) = %d ........... ...\n",iRet);
strcpy(data, "hellozadsfaddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd");
printf(" dataLinux = %s ........... ...\n",data);
};
void fooNullPointerAccess()
{
foo3();
};
void fooLoop()
{
while(true)
{
}
};
};
int main ( int argc, char * * argv ) {
signal(SIGINT , intrupt); // register a SIGINT handler
signal(SIGTERM , term); // register a SIGTERM handler
signal(SIGABRT , abort); // register a SIGABRT handler
signal(SIGFPE , floatingPoint); // register a SIGFPE handler
signal(SIGILL , IllegalInstruction); // register a Illegal instruction handler
signal(SIGSEGV , IllegalStorage); // register a Illegal storage handler
int iRet;
bool bErr = false;
printf("Starting Server on queue %s...\n","Demo test");
try
{
printf("IN TRY........... ...\n");
iRet = 0;
iRet = iRet/0.;
printf(" iRet = %d ........... ...\n",iRet);
//foo();
// foo2();
Crash crsh;
// crsh.fooArrayOutOfIndex();
crsh.fooNullPointerAccess();
// crsh.fooLoop();
}
catch(...)
{
bErr = true;
printf("***************** ERROR ****************** .\n");
}
printf("Connected and Running ... \n");
printf("END Server \n ");
return 1;
}
enjoy
Yaniv
No comments:
Post a Comment