Я пытаюсь написать обработчик сигнала, который должен знать pid процесса, который отправляет сигнал.Мне не повезло с получением чего-либо полезного из siginfo_t
, переданного в мой обработчик на macOS 10.14 с Xcode 10.
Я сократил свой код до минимального примера ниже, чтобы продемонстрировать проблему.В этом примере я порождаю дочерний процесс для отправки сигнала, который я хочу протестировать, по умолчанию SIGTERM
, но никакой другой сигнал, который я пробовал, не работает лучше.
Предполагается, что вы хотите собрать и протестировать этона Mac вы, вероятно, захотите сказать lldb не останавливаться при получении сигнала.Вы можете использовать эту команду lldb: pro hand -p true -s false SIGTERM
.
Я также компилирую с C ++, но я полагаю, что все это вырезано, и пример кода теперь должен быть чистым C.
Обратите внимание, что не имеет значения, исходит ли сигнал от дочернего элемента, терминала или другого процесса, результатом всегда является то, что si_pid
всегда равно 0 (вместе со всем, кроме si_signo
и si_addr
).Неважно, сколько раз я посылаю сигнал, так что, похоже, это не просто условие гонки.
Как я могу получить pid процесса, отправляющего сигнал на macOS 10.14?Я не припоминаю, чтобы эта проблема возникла 10.12, что я и использовал раньше.
Это всего лишь пример для решения проблемы, поэтому, пожалуйста, игнорируйте все, что на самом деле не вызывает проблемы.
Если код выглядит так, как будто он должен работать так, как я ожидал, тогда мне было бы интересно увидеть комментарии о системах, на которых он работает.
#include <unistd.h>
#include <signal.h>
#include <stdio.h>
volatile sig_atomic_t histogram[3] = {0,0,0};
volatile sig_atomic_t signaled = 0;
const int testsig = SIGTERM;
void sigaction_handler(int sig, siginfo_t* info, void* context)
{
switch (info->si_pid) {
case 0:
case 1:
histogram[info->si_pid]++;
break;
default:
histogram[2]++;
break;
}
signaled = 1;
}
int main(int argc, const char * argv[]) {
pid_t mainpid = getpid();
pid_t pid = fork();
if (pid == 0) {
while (kill(mainpid, 0) == 0) {
sleep(1);
kill(mainpid, testsig);
}
_exit(0);
}
struct sigaction sigAction;
memset( &sigAction, 0, sizeof( sigAction ) );
sigAction.sa_sigaction = sigaction_handler;
sigemptyset (&sigAction.sa_mask);
sigAction.sa_flags = SA_SIGINFO;
sigaction(testsig, &sigAction, NULL);
while (1) {
if (signaled) {
printf("pid 0: %d, pid 1: %d, others: %d\n", histogram[0], histogram[1], histogram[2]);
signaled = 0;
}
sleep(1);
}
}