summaryrefslogtreecommitdiff
path: root/src/lib/eina/eina_debug_bt.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/eina/eina_debug_bt.c')
-rw-r--r--src/lib/eina/eina_debug_bt.c85
1 files changed, 83 insertions, 2 deletions
diff --git a/src/lib/eina/eina_debug_bt.c b/src/lib/eina/eina_debug_bt.c
index 21b067c395..f38dcd481a 100644
--- a/src/lib/eina/eina_debug_bt.c
+++ b/src/lib/eina/eina_debug_bt.c
@@ -37,7 +37,65 @@
#ifndef _WIN32
# include <signal.h>
-# define SIG SIGPROF
+// realtime signals guarantee a minimum of 8, so SIGRTMIN + 7 would be valid
+// at a minimum, so let's choose + 6 ... second last of the minimum set.
+// SIGRTMAX of course is defined too... note the manual pages for sigation say
+// that it calls rt_sigaction transparently for us so... no need for anything
+// else special
+# ifdef SIGRTMIN
+# define SIG (SIGRTMIN + 6)
+# else
+// OSX seems to not support posix RT signals... too old a kernel. so be partly
+// broken on OSX in that a HUP signal will maybe cause a crash... but compiling
+// with -pg would have guaranteed always caused a crash before anyway.
+// given OSX only supports "old-style" signals like:
+//
+// #define SIGHUP 1 /* hangup */
+// #define SIGINT 2 /* interrupt */
+// #define SIGQUIT 3 /* quit */
+// #define SIGILL 4 /* illegal instruction (not reset when caught) */
+// #define SIGTRAP 5 /* trace trap (not reset when caught) */
+// #define SIGABRT 6 /* abort() */
+// #if (defined(_POSIX_C_SOURCE) && !defined(_DARWIN_C_SOURCE))
+// # define SIGPOLL 7 /* pollable event ([XSR] generated, not supported) */
+// #else /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */
+// # define SIGIOT SIGABRT /* compatibility */
+// # define SIGEMT 7 /* EMT instruction */
+// #endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */
+// #define SIGFPE 8 /* floating point exception */
+// #define SIGKILL 9 /* kill (cannot be caught or ignored) */
+// #define SIGBUS 10 /* bus error */
+// #define SIGSEGV 11 /* segmentation violation */
+// #define SIGSYS 12 /* bad argument to system call */
+// #define SIGPIPE 13 /* write on a pipe with no one to read it */
+// #define SIGALRM 14 /* alarm clock */
+// #define SIGTERM 15 /* software termination signal from kill */
+// #define SIGURG 16 /* urgent condition on IO channel */
+// #define SIGSTOP 17 /* sendable stop signal not from tty */
+// #define SIGTSTP 18 /* stop signal from tty */
+// #define SIGCONT 19 /* continue a stopped process */
+// #define SIGCHLD 20 /* to parent on child stop or exit */
+// #define SIGTTIN 21 /* to readers pgrp upon background tty read */
+// #define SIGTTOU 22 /* like TTIN for output if (tp->t_local&LTOSTOP) */
+// #if (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE))
+// # define SIGIO 23 /* input/output possible signal */
+// #endif
+// #define SIGXCPU 24 /* exceeded CPU time limit */
+// #define SIGXFSZ 25 /* exceeded file size limit */
+// #define SIGVTALRM 26 /* virtual time alarm */
+// #define SIGPROF 27 /* profiling time alarm */
+// #if (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE))
+// # define SIGWINCH 28 /* window size changes */
+// # define SIGINFO 29 /* information request */
+// #endif
+// #define SIGUSR1 30 /* user defined signal 1 */
+// #define SIGUSR2 31 /* user defined signal 2 */
+//
+// (excerpt from OSX's signal.h - found at:
+// http://github.com/st3fan/osx-10.9/blob/master/xnu-2422.1.72/bsd/sys/signal.h
+// pasting here due to how difficult it was to find a signal list for OSX)
+# define SIG SIGHUP
+# endif
#endif
static Eina_Semaphore _wait_for_bts_sem;
@@ -52,6 +110,10 @@ static int *_bt_cpu;
static double _trace_t0 = 0.0;
static Eina_Debug_Timer *_timer = NULL;
+#ifndef _WIN32
+static struct sigaction old_sigprof_action;
+#endif
+
void
_eina_debug_dump_fhandle_bt(FILE *f, void **bt, int btlen)
{
@@ -196,6 +258,15 @@ _signal_init(void)
#ifndef _WIN32
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
// obey this (this is the case on linux - other OSs may vary)
sa.sa_sigaction = _signal_handler;
@@ -213,6 +284,14 @@ _signal_init(void)
}
static void
+_signal_shutdown(void)
+{
+#ifndef _WIN32
+ sigaction(SIG, &old_sigprof_action, NULL);
+#endif
+}
+
+static void
_collect_bt(pthread_t pth)
{
// this async signals the thread to switch to the deebug signal handler
@@ -290,6 +369,8 @@ static Eina_Bool
_prof_on_cb(Eina_Debug_Session *session, int cid EINA_UNUSED, void *buffer, int size)
{
unsigned int time;
+
+ _signal_init();
if (size >= 4)
{
memcpy(&time, buffer, 4);
@@ -305,6 +386,7 @@ _prof_off_cb(Eina_Debug_Session *session EINA_UNUSED, int cid EINA_UNUSED, void
{
eina_debug_timer_del(_timer);
_timer = NULL;
+ _signal_shutdown();
return EINA_TRUE;
}
@@ -317,7 +399,6 @@ EINA_DEBUG_OPCODES_ARRAY_DEFINE(_OPS,
Eina_Bool
_eina_debug_bt_init(void)
{
- _signal_init();
eina_semaphore_new(&_wait_for_bts_sem, 0);
eina_debug_opcodes_register(NULL, _OPS(), NULL, NULL);
return EINA_TRUE;