Files
pstrace/main.cpp
T
nnosov 8f7fed23dc global refactoring: use libunwind to get stack frame, get rid on process
base address, better DWARF DW_OP_XXX handling, initial implementation of
parameter's values retrieval
2020-01-09 18:49:45 +04:00

201 lines
4.3 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//system
#include <iostream>
#include <stdlib.h>
#include <fcntl.h>
#include "logger/log_console.h"
#include "sysutils.h"
static SC_LogConsole log_local(0, "/tmp/unspecified.file");
SC_LogBase* logger = &log_local;
typedef enum {
DEF_1 = 1,
DEF_2,
DEF_3
} my_int;
void Fun2(int arg1, uint32_t arg2)
{
int* ptr = NULL;
*ptr = arg1;
}
uint32_t Fun1(const int arg1, my_int arg2, uint32_t arg3)
{
int my_local = arg1 + 2;
printf("%d", my_local);
Fun2(my_local, arg3);
return arg2;
}
#include <ucontext.h>
#include <execinfo.h>
#include <cxxabi.h>
#include <signal.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
typedef void (*sig_handler_t)(int sig);
void SetSignalHandler(sig_handler_t handler = 0);
void SigusrHandler(int sig)
{
// just do nothing on SIGUSR1 & SIGUSR2
SetSignalHandler(SigusrHandler);
}
volatile sig_atomic_t fatal_error_in_progress = 0;
void FatalSignalHandler(int sig, siginfo_t* info, void* context)
{
// 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;
logger->Log(SEVERITY_ERROR, "%s signal handled", strsignal(sig));
bool trace = false;
pst_context ctx((ucontext_t*)context);
if((context != 0) && (sig == SIGSEGV || sig == SIGABRT || sig == SIGBUS || sig == SIGFPE))
{
trace = ctx.unwind();
}
if(trace) {
logger->Log(SEVERITY_DEBUG, "%s", ctx.buff);
} else {
logger->Log(SEVERITY_ERROR, "No stack trace obtained");
}
// comment out line below to prevent coredump
// exit(EXIT_FAILURE);
// Now reraise the signal.
// We reactivate the signal’s default handling, which is to terminate the process.
// We could just call exit or abort, but reraising the signal sets the return status
// from the process correctly.
signal (sig, SIG_DFL);
raise (sig);
}
void SignalHandler(int sig)
{
// if (handled_error_in_progress)
// raise (sig);
// handled_error_in_progress = 1;
// const char* str_sig = strsignal(sig);
// logger->Log(SEVERITY_INFO, "%s received.", str_sig);
if(sig == SIGUSR1) {
logger->Log(SEVERITY_INFO, "Maintenance mode enabled.");
} else if(sig == SIGUSR2) {
logger->Log(SEVERITY_INFO, "Maintenance mode disabled.");
}
// signal (sig, SIG_DFL);
// raise(sig);
// reset to our handler back
SetSignalHandler();
}
#include <sys/time.h>
#include <sys/resource.h>
void SetSignalHandler(sig_handler_t handler)
{
//signals set
sigset_t ss;
sigfillset(&ss);
//remove previous handlers
// sigdelset(&ss, SIGINT);
sigdelset(&ss, SIGUSR1);
sigdelset(&ss, SIGUSR2);
sigdelset(&ss, SIGSEGV);
sigdelset(&ss, SIGABRT);
sigdelset(&ss, SIGBUS);
sigdelset(&ss, SIGFPE);
sigdelset(&ss, SIGCHLD);
sigdelset(&ss, SIGTERM); //without replacement
//signal action
struct sigaction sa;
sa.sa_flags = SA_SIGINFO;
sa.sa_mask = ss;
// cleanup
sa.sa_handler = NULL;
sa.sa_sigaction = NULL;
// //set interrupt signal
// sa.sa_handler = SignalHandler;
// sigaction(SIGINT, &sa, 0);
//set stop signal
sa.sa_handler = (handler == NULL) ? SignalHandler : handler;
sigaction(SIGUSR1, &sa, 0);
sa.sa_handler = SignalHandler;
sigaction(SIGUSR2, &sa, 0);
// cleanup
sa.sa_handler = NULL;
sa.sa_sigaction = NULL;
//set SIGSEGV
sa.sa_sigaction = FatalSignalHandler;
sigaction(SIGSEGV, &sa, 0);
//set SIGABRT
sa.sa_sigaction = FatalSignalHandler;
sigaction(SIGABRT, &sa, 0);
//set SIGBUS
sa.sa_sigaction = FatalSignalHandler;
sigaction(SIGBUS, &sa, 0);
//set FPE signal
sa.sa_sigaction = FatalSignalHandler;
sigaction(SIGFPE, &sa, 0);
//enable signals set
sigprocmask(SIG_BLOCK, &ss, 0);
//set core dump size to 1Gb
struct rlimit limit;
limit.rlim_cur = 1073741824;
limit.rlim_max = 1073741824;
if (setrlimit(RLIMIT_CORE, &limit))
{
logger->Log(SEVERITY_DEBUG, "Failed to set limit for core dump file size");
}
}
void ResetSignalHandler() {
signal(SIGINT, SIG_DFL);
signal(SIGABRT, SIG_DFL);
signal(SIGTERM, SIG_DFL);
signal(SIGSEGV, SIG_DFL);
signal(SIGUSR1, SIG_DFL);
signal(SIGUSR2, SIG_DFL);
signal(SIGCHLD, SIG_DFL);
}
int main(int argc, char* argv[])
{
SetSignalHandler(SigusrHandler);
Fun1(1, DEF_2, 5);
return 0;
}