diff --git a/libs/wine/debug.c b/libs/wine/debug.c index 6f4167f..ee4d631 100644 --- a/libs/wine/debug.c +++ b/libs/wine/debug.c @@ -26,9 +26,15 @@ #include #include #include #include +#include + +#ifdef HAVE_SYS_SIGNAL_H +# include +#endif #include "wine/debug.h" #include "wine/library.h" +#include "wine/pthread.h" static const char * const debug_classes[] = { "fixme", "err", "warn", "trace" }; @@ -36,10 +42,51 @@ #define MAX_DEBUG_OPTIONS 256 static unsigned char default_flags = (1 << __WINE_DBCL_ERR) | (1 << __WINE_DBCL_FIXME); static unsigned int nb_debug_options = 0; +static volatile sig_atomic_t enable_logging = 1; static struct __wine_debug_channel debug_options[MAX_DEBUG_OPTIONS]; static struct __wine_debug_functions funcs; +static void rt0_handler( int signal, siginfo_t *siginfo, void *sigcontext ) +{ + enable_logging = 0; +} + +static void rt1_handler( int signal, siginfo_t *siginfo, void *sigcontext ) +{ + enable_logging = 1; +} + +static void setup_signals() +{ +#ifdef linux + struct sigaction sig_act; + sigset_t mask; + static struct wine_pthread_functions pthread_functions; + + wine_pthread_get_functions( &pthread_functions, sizeof(pthread_functions) ); + + memset(&sig_act, 0, sizeof(struct sigaction)); + sigemptyset(&sig_act.sa_mask); + sig_act.sa_flags = SA_SIGINFO | SA_RESTART; + sig_act.sa_sigaction = rt0_handler; + if (sigaction( SIGRTMIN, &sig_act, NULL ) == -1) goto error; + printf("pid %u registered signal %d to disable logging\n", getpid(), SIGRTMIN); + sig_act.sa_sigaction = rt1_handler; + if (sigaction( SIGRTMIN+1, &sig_act, NULL ) == -1) goto error; + printf("pid %u registered signal %d to enable logging\n", getpid(), SIGRTMIN+1); + sigemptyset(&mask); + sigaddset(&mask, SIGRTMIN); + sigaddset(&mask, SIGRTMIN+1); + pthread_functions.sigprocmask(SIG_UNBLOCK, &mask, NULL); + return; + +error: + printf("Could not register signal handler!\n"); +#endif + ; +} + static int cmp_name( const void *p1, const void *p2 ) { const char *name = p1; @@ -50,7 +97,7 @@ static int cmp_name( const void *p1, con /* get the flags to use for a given channel, possibly setting them too in case of lazy init */ unsigned char __wine_dbg_get_channel_flags( struct __wine_debug_channel *channel ) { - if (nb_debug_options) + if (nb_debug_options && enable_logging) { struct __wine_debug_channel *opt = bsearch( channel->name, debug_options, nb_debug_options, sizeof(debug_options[0]), cmp_name ); @@ -185,6 +232,8 @@ void debug_init(void) { if (!strcmp( wine_debug, "help" )) debug_usage(); parse_options( wine_debug ); + if (getenv("WINEDEBUGSIG")) + setup_signals(); } }