/* orxonox - the future of 3D-vertical-scrollers Copyright (C) 2004 orx This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. ### File Specific: main-programmer: Christoph Renner co-programmer: ... */ #include "signal_handler.h" #include #ifdef __LINUX__ SignalHandler * SignalHandler::singletonRef = NULL; SignalHandler::SignalHandler() { } void SignalHandler::doCatch( std::string appName, GdbRunType type ) { this->type = type; this->appName = appName; catchSignal( SIGSEGV ); catchSignal( SIGABRT ); } void SignalHandler::dontCatch() { for ( SignalRecList::iterator it = sigRecList.begin(); it != sigRecList.end(); it++ ) { signal( it->signal, it->handler ); } sigRecList.clear(); } void SignalHandler::catchSignal( int sig ) { sighandler_t handler = signal( sig, SignalHandler::sigHandler ); assert( handler != SIG_ERR ); SignalRec rec; rec.signal = sig; rec.handler = handler; sigRecList.push_front( rec ); } void SignalHandler::sigHandler( int sig ) { std::string sigName = "UNKNOWN"; switch ( sig ) { case SIGSEGV: sigName = "SIGSEGV"; break; case SIGABRT: sigName = "SIGABRT"; break; } printf( "recieved signal %s\ntry to write backtrace to file orxonox.backtrace\n", sigName.c_str() ); int fd[2]; assert( pipe(fd) != -1 ); int pid = fork(); assert( pid != -1 ); if ( pid == 0 ) { getInstance()->dontCatch(); sleep(2); return; } else { if ( getInstance()->type == GDB_RUN_WRITE_TO_FILE && fork() == 0 ) { sleep(1); write( fd[1], "c\nbt\nq\n", 7 ); exit(0); } char command[256]; if ( getInstance()->type == GDB_RUN_WRITE_TO_FILE ) { dup2( fd[0], STDIN_FILENO ); snprintf( command, 255, "gdb -p %d %s 1>" GDB_BT_FILE " 2>&1", pid, getInstance()->appName.c_str() ); } else snprintf( command, 255, "gdb -p %d %s", pid, getInstance()->appName.c_str() ); execlp( "sh", "sh", "-c", command, (void*)NULL); } } #endif /* __WIN32__ */