Skip to content

Commit

Permalink
#759: Discover available profiling signal automatically
Browse files Browse the repository at this point in the history
  • Loading branch information
apangin committed Mar 16, 2024
1 parent 1be8838 commit 397f450
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 3 deletions.
2 changes: 1 addition & 1 deletion src/ctimer_linux.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ Error CTimer::start(Arguments& args) {
}
_interval = args._interval ? args._interval : DEFAULT_INTERVAL;
_cstack = args._cstack;
_signal = args._signal == 0 ? SIGPROF : args._signal & 0xff;
_signal = args._signal == 0 ? OS::getProfilingSignal(0) : args._signal & 0xff;

int max_timers = OS::getMaxThreadId();
if (max_timers != _max_timers) {
Expand Down
1 change: 1 addition & 0 deletions src/os.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ class OS {

static SigAction installSignalHandler(int signo, SigAction action, SigHandler handler = NULL);
static SigAction replaceCrashHandler(SigAction action);
static int getProfilingSignal(int mode);
static bool sendSignalToThread(int thread_id, int signo);

static void* safeAlloc(size_t size);
Expand Down
27 changes: 27 additions & 0 deletions src/os_linux.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ JitWriteProtection::~JitWriteProtection() {
}


static SigAction installed_sigaction[64];

const size_t OS::page_size = sysconf(_SC_PAGESIZE);
const size_t OS::page_mask = OS::page_size - 1;

Expand Down Expand Up @@ -235,6 +237,9 @@ SigAction OS::installSignalHandler(int signo, SigAction action, SigHandler handl
} else {
sa.sa_sigaction = action;
sa.sa_flags = SA_SIGINFO | SA_RESTART;
if (signo > 0 && signo < sizeof(installed_sigaction) / sizeof(installed_sigaction[0])) {
installed_sigaction[signo] = action;
}
}

sigaction(signo, &sa, &oldsa);
Expand All @@ -250,6 +255,28 @@ SigAction OS::replaceCrashHandler(SigAction action) {
return old_action;
}

int OS::getProfilingSignal(int mode) {
static int preferred_signals[2] = {SIGPROF, SIGVTALRM};

const u64 allowed_signals =
1ULL << SIGPROF | 1ULL << SIGVTALRM | 1ULL << SIGSTKFLT | 1ULL << SIGPWR | -(1ULL << SIGRTMIN);

int& signo = preferred_signals[mode];
int initial_signo = signo;
int other_signo = preferred_signals[1 - mode];

do {
struct sigaction sa;
if ((allowed_signals & (1ULL << signo)) != 0 && signo != other_signo && sigaction(signo, NULL, &sa) == 0) {
if (sa.sa_handler == SIG_DFL || sa.sa_handler == SIG_IGN || sa.sa_sigaction == installed_sigaction[signo]) {
return signo;
}
}
} while ((signo = (signo + 53) & 63) != initial_signo);

return signo;
}

bool OS::sendSignalToThread(int thread_id, int signo) {
return syscall(__NR_tgkill, processId(), thread_id, signo) == 0;
}
Expand Down
27 changes: 27 additions & 0 deletions src/os_macos.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ JitWriteProtection::~JitWriteProtection() {
}


static SigAction installed_sigaction[32];

const size_t OS::page_size = sysconf(_SC_PAGESIZE);
const size_t OS::page_mask = OS::page_size - 1;

Expand Down Expand Up @@ -204,6 +206,9 @@ SigAction OS::installSignalHandler(int signo, SigAction action, SigHandler handl
} else {
sa.sa_sigaction = action;
sa.sa_flags = SA_SIGINFO | SA_RESTART;
if (signo > 0 && signo < sizeof(installed_sigaction) / sizeof(installed_sigaction[0])) {
installed_sigaction[signo] = action;
}
}

sigaction(signo, &sa, &oldsa);
Expand All @@ -219,6 +224,28 @@ SigAction OS::replaceCrashHandler(SigAction action) {
return old_action;
}

int OS::getProfilingSignal(int mode) {
static int preferred_signals[2] = {SIGPROF, SIGVTALRM};

const u64 allowed_signals =
1ULL << SIGPROF | 1ULL << SIGVTALRM | 1ULL << SIGEMT | 1ULL << SIGSYS;

int& signo = preferred_signals[mode];
int initial_signo = signo;
int other_signo = preferred_signals[1 - mode];

do {
struct sigaction sa;
if ((allowed_signals & (1ULL << signo)) != 0 && signo != other_signo && sigaction(signo, NULL, &sa) == 0) {
if (sa.sa_handler == SIG_DFL || sa.sa_handler == SIG_IGN || sa.sa_sigaction == installed_sigaction[signo]) {
return signo;
}
}
} while ((signo = (signo + 1) & 31) != initial_signo);

return signo;
}

bool OS::sendSignalToThread(int thread_id, int signo) {
#ifdef __aarch64__
register long x0 asm("x0") = thread_id;
Expand Down
2 changes: 1 addition & 1 deletion src/perfEvents_linux.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -779,7 +779,7 @@ Error PerfEvents::start(Arguments& args) {
}
_interval = args._interval ? args._interval : _event_type->default_interval;
_cstack = args._cstack;
_signal = args._signal == 0 ? SIGPROF : args._signal & 0xff;
_signal = args._signal == 0 ? OS::getProfilingSignal(0) : args._signal & 0xff;

_ring = args._ring;
if (_ring != RING_USER && !Symbols::haveKernelSymbols()) {
Expand Down
3 changes: 2 additions & 1 deletion src/wallClock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ Error WallClock::start(Arguments& args) {
_interval = _sample_idle_threads ? DEFAULT_INTERVAL * 5 : DEFAULT_INTERVAL;
}

_signal = args._signal == 0 ? SIGVTALRM : ((args._signal >> 8) > 0 ? args._signal >> 8 : args._signal);
_signal = args._signal == 0 ? OS::getProfilingSignal(1)
: ((args._signal >> 8) > 0 ? args._signal >> 8 : args._signal);
OS::installSignalHandler(_signal, signalHandler);

_running = true;
Expand Down

0 comments on commit 397f450

Please sign in to comment.