eina_debug_bt: only enable SIGPROF handler when profiling is enabled

Summary:
if profiling is not enabled then reaching this signal handler will always
result in a crash

moreover, the signal handler has no functional value if profiling is not active,
so do not add it until that point

fix T7028

@fix
Depends on D6311

Reviewers: ManMower, devilhorns

Reviewed By: ManMower

Subscribers: cedric, #committers

Tags: #efl

Maniphest Tasks: T7028

Differential Revision: https://phab.enlightenment.org/D6312
This commit is contained in:
Mike Blumenkrantz 2018-06-19 14:04:45 -04:00
parent 00bc3af4dd
commit 217f30001a
1 changed files with 22 additions and 1 deletions

View File

@ -52,6 +52,10 @@ static int *_bt_cpu;
static double _trace_t0 = 0.0; static double _trace_t0 = 0.0;
static Eina_Debug_Timer *_timer = NULL; static Eina_Debug_Timer *_timer = NULL;
#ifndef _WIN32
static struct sigaction old_sigprof_action;
#endif
void void
_eina_debug_dump_fhandle_bt(FILE *f, void **bt, int btlen) _eina_debug_dump_fhandle_bt(FILE *f, void **bt, int btlen)
{ {
@ -196,6 +200,15 @@ _signal_init(void)
#ifndef _WIN32 #ifndef _WIN32
struct sigaction sa; struct sigaction sa;
memset(&sa, 0, sizeof(struct sigaction));
sa.sa_handler = SIG_DFL;
sa.sa_sigaction = NULL;
sa.sa_flags = SA_RESTART | SA_SIGINFO;
sigemptyset(&sa.sa_mask);
sigaction(SIG, &sa, &old_sigprof_action);
memset(&sa, 0, sizeof(struct sigaction));
// set up signal handler for our profiling signal - eevery thread should // set up signal handler for our profiling signal - eevery thread should
// obey this (this is the case on linux - other OSs may vary) // obey this (this is the case on linux - other OSs may vary)
sa.sa_sigaction = _signal_handler; sa.sa_sigaction = _signal_handler;
@ -212,6 +225,12 @@ _signal_init(void)
#endif #endif
} }
static void
_signal_shutdown(void)
{
sigaction(SIG, &old_sigprof_action, NULL);
}
static void static void
_collect_bt(pthread_t pth) _collect_bt(pthread_t pth)
{ {
@ -290,6 +309,8 @@ static Eina_Bool
_prof_on_cb(Eina_Debug_Session *session, int cid EINA_UNUSED, void *buffer, int size) _prof_on_cb(Eina_Debug_Session *session, int cid EINA_UNUSED, void *buffer, int size)
{ {
unsigned int time; unsigned int time;
_signal_init();
if (size >= 4) if (size >= 4)
{ {
memcpy(&time, buffer, 4); memcpy(&time, buffer, 4);
@ -305,6 +326,7 @@ _prof_off_cb(Eina_Debug_Session *session EINA_UNUSED, int cid EINA_UNUSED, void
{ {
eina_debug_timer_del(_timer); eina_debug_timer_del(_timer);
_timer = NULL; _timer = NULL;
_signal_shutdown();
return EINA_TRUE; return EINA_TRUE;
} }
@ -317,7 +339,6 @@ EINA_DEBUG_OPCODES_ARRAY_DEFINE(_OPS,
Eina_Bool Eina_Bool
_eina_debug_bt_init(void) _eina_debug_bt_init(void)
{ {
_signal_init();
eina_semaphore_new(&_wait_for_bts_sem, 0); eina_semaphore_new(&_wait_for_bts_sem, 0);
eina_debug_opcodes_register(NULL, _OPS(), NULL, NULL); eina_debug_opcodes_register(NULL, _OPS(), NULL, NULL);
return EINA_TRUE; return EINA_TRUE;