-
Notifications
You must be signed in to change notification settings - Fork 604
Open
Labels
Description
Perhaps this is a more of a known limitation than a bug but I have come across an application in the wild that has a thread which blocks all signals using pthread_sigmask() then handles signals by calling sigwaitinfo() in a loop.
When statically linking DynamoRIO into the app we are unable to take over the signal handling thread because SIGILL is blocked.
We are able to work around it by modifying the app to unblock SIGILL but perhaps there is a way for DynamoRIO to unblock SIGILL before attempting to attach (perhaps using ptrace if it is not possible using regular APIs).
Here is a test app that reproduces the issue:
#include "configure.h"
#include "dr_api.h"
#include "tools.h"
#include "condvar.h"
#include "thread.h"
#include <errno.h>
#include <signal.h>
#ifndef UNIX
# error UNIX-only
#endif
static void *signals_blocked;
static THREAD_FUNC_RETURN_TYPE
sig_thread(void *arg)
{
sigset_t set;
siginfo_t info;
int res;
sigfillset(&set);
res = pthread_sigmask(SIG_BLOCK, &set, NULL);
assert(res == 0);
print("sig_thread blocked signals\n");
signal_cond_var(signals_blocked);
while (true) {
res = sigwaitinfo(&set, &info);
if (res == -1) {
if (errno == EINTR)
continue;
}
assert(res != -1);
if (res == SIGUSR1) {
print("sig_thread received SIGUSR1\n");
break;
}
}
return NULL;
}
DR_EXPORT void
dr_client_main(client_id_t id, int argc, const char *argv[])
{
print("in dr_client_main\n");
}
int
main(int argc, const char *argv[])
{
signals_blocked = create_cond_var();
print("starting sig_thread\n");
thread_t thread = create_thread(sig_thread, NULL);
wait_cond_var(signals_blocked);
print("pre-DR start\n");
assert(!dr_app_running_under_dynamorio());
dr_app_setup_and_start(); /* This call will hang because we can't attach to sig_thread. */
assert(dr_app_running_under_dynamorio());
print("sending SIGUSR1 to sig_thread\n");
pthread_kill(thread, SIGUSR1);
join_thread(thread);
print("pre-DR stop\n");
dr_app_stop_and_cleanup();
assert(!dr_app_running_under_dynamorio());
destroy_cond_var(signals_blocked);
print("all done\n");
return 0;
}
Reactions are currently unavailable