mirror of
https://github.com/edubart/otclient.git
synced 2025-04-30 01:29:21 +02:00
118 lines
4.8 KiB
C++
118 lines
4.8 KiB
C++
/*
|
|
* Copyright (c) 2010-2011 OTClient <https://github.com/edubart/otclient>
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
* of this software and associated documentation files (the "Software"), to deal
|
|
* in the Software without restriction, including without limitation the rights
|
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
* copies of the Software, and to permit persons to whom the Software is
|
|
* furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in
|
|
* all copies or substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
* THE SOFTWARE.
|
|
*/
|
|
|
|
|
|
#ifdef HANDLE_EXCEPTIONS
|
|
|
|
#include <csignal>
|
|
#include <execinfo.h>
|
|
|
|
#define MAX_BACKTRACE_DEPTH 128
|
|
#define DEMANGLE_BACKTRACE_SYMBOLS
|
|
|
|
void crashHandler(int signum, siginfo_t* info, void* secret)
|
|
{
|
|
logError("Application crashed");
|
|
|
|
ucontext_t context = *(ucontext_t*)secret;
|
|
time_t tnow;
|
|
char fileName[128];
|
|
time(&tnow);
|
|
tm *ts = localtime(&tnow);
|
|
strftime(fileName, 128, (x11.appName + "-crash_-%d-%m-%Y_%H:%M:%S.txt").c_str(), ts);
|
|
|
|
std::stringstream ss;
|
|
ss.flags(std::ios::hex | std::ios::showbase);
|
|
#if __WORDSIZE == 32
|
|
ss <<
|
|
ss << " at eip = " << context.uc_mcontext.gregs[REG_EIP] << std::endl;
|
|
ss << " eax = " << context.uc_mcontext.gregs[REG_EAX] << std::endl;
|
|
ss << " ebx = " << context.uc_mcontext.gregs[REG_EBX] << std::endl;
|
|
ss << " ecx = " << context.uc_mcontext.gregs[REG_ECX] << std::endl;
|
|
ss << " edx = " << context.uc_mcontext.gregs[REG_EDX] << std::endl;
|
|
ss << " esi = " << context.uc_mcontext.gregs[REG_ESI] << std::endl;
|
|
ss << " edi = " << context.uc_mcontext.gregs[REG_EDI] << std::endl;
|
|
ss << " ebp = " << context.uc_mcontext.gregs[REG_EBP] << std::endl;
|
|
ss << " esp = " << context.uc_mcontext.gregs[REG_ESP] << std::endl;
|
|
ss << " efl = " << context.uc_mcontext.gregs[REG_EFL] << std::endl;
|
|
#else // 64-bit
|
|
ss << " at rip = " << context.uc_mcontext.gregs[REG_RIP] << std::endl;
|
|
ss << " rax = " << context.uc_mcontext.gregs[REG_RAX] << std::endl;
|
|
ss << " rbx = " << context.uc_mcontext.gregs[REG_RBX] << std::endl;
|
|
ss << " rcx = " << context.uc_mcontext.gregs[REG_RCX] << std::endl;
|
|
ss << " rdx = " << context.uc_mcontext.gregs[REG_RDX] << std::endl;
|
|
ss << " rsi = " << context.uc_mcontext.gregs[REG_RSI] << std::endl;
|
|
ss << " rdi = " << context.uc_mcontext.gregs[REG_RDI] << std::endl;
|
|
ss << " rbp = " << context.uc_mcontext.gregs[REG_RBP] << std::endl;
|
|
ss << " rsp = " << context.uc_mcontext.gregs[REG_RSP] << std::endl;
|
|
ss << " efl = " << context.uc_mcontext.gregs[REG_EFL] << std::endl;
|
|
#endif
|
|
ss << std::endl;
|
|
ss.flags(std::ios::dec);
|
|
ss << " backtrace:" << std::endl;
|
|
|
|
void* buffer[MAX_BACKTRACE_DEPTH];
|
|
int numLevels = backtrace(buffer, MAX_BACKTRACE_DEPTH);
|
|
char **tracebackBuffer = backtrace_symbols(buffer, numLevels);
|
|
if(tracebackBuffer) {
|
|
for(int i = 2; i < numLevels; i++) {
|
|
std::string line = tracebackBuffer[i];
|
|
if(line.find("__libc_start_main") != std::string::npos)
|
|
break;
|
|
#ifdef DEMANGLE_BACKTRACE_SYMBOLS
|
|
std::size_t demanglePos = line.find("(_Z");
|
|
if(demanglePos != std::string::npos) {
|
|
demanglePos++;
|
|
int len = std::min(line.find_first_of("+", demanglePos), line.find_first_of(")", demanglePos)) - demanglePos;
|
|
std::string funcName = line.substr(demanglePos, len);
|
|
line.replace(demanglePos, len, Fw::demangleName(funcName.c_str()));
|
|
}
|
|
#endif
|
|
ss << " " << i-1 << ": " << line << std::endl;
|
|
}
|
|
free(tracebackBuffer);
|
|
}
|
|
|
|
logInfo(ss.str());
|
|
|
|
std::ofstream out(fileName);
|
|
out << ss.str();
|
|
out.close();
|
|
logInfo("Crash report saved to file ", fileName);
|
|
|
|
signal(SIGILL, SIG_DFL);
|
|
signal(SIGSEGV, SIG_DFL);
|
|
signal(SIGFPE, SIG_DFL);
|
|
}
|
|
#endif
|
|
|
|
|
|
#ifdef HANDLE_EXCEPTIONS
|
|
struct sigaction sa;
|
|
sa.sa_sigaction = &crashHandler;
|
|
sigemptyset (&sa.sa_mask);
|
|
sa.sa_flags = SA_RESTART | SA_SIGINFO;
|
|
|
|
sigaction(SIGILL, &sa, NULL); // illegal instruction
|
|
sigaction(SIGSEGV, &sa, NULL); // segmentation fault
|
|
sigaction(SIGFPE, &sa, NULL); // floating-point exception
|
|
#endif |