我遇到了Go程序使用.so lib的问题,而c代码需要处理SIGALRM信号.但似乎一旦信号SIGALRM发布,程序就会崩溃.从"The Go Programming Language"我看到:
如果非Go代码安装任何信号处理程序,则必须使用带有sigaction的SA_ONSTACK标志.如果未收到信号,则可能导致程序崩溃.
任何人都可以通过sigaction显示SA_ONSTACK标志的用法.我非常感激.
以下是我的代码:
// LIC_TIMER_CALLBACK_FUNC is a function pointer
static LIC_TIMER_CALLBACK_FUNC s_pfnTmCallBack;
static void _OS_TriggerTask(int iSig)
{
logInfo("_OS_TriggerTask start...");
if (LIC_NULL_PTR != s_pfnTmCallBack)
{
logInfo("call timer callback...");
s_pfnTmCallBack(0);
}
logInfo("_OS_TriggerTask end...");
}
// set the trigger
int OS_StartTrigger(int ulLength, LIC_TIMER_CALLBACK_FUNC pfnTmCallBack)
{
logInfo("OS_StartTrigger start...");
s_pfnTmCallBack = pfnTmCallBack;
struct sigaction stSigact;
stSigact.sa_handler = _OS_TriggerTask;
stSigact.sa_flags = SA_ONSTACK;
sigemptyset(&stSigact.sa_mask);
int iRet = sigaction(SIGALRM, &stSigact, NULL);
if(0 != iRet)
{
logError("set signal failed...");
}
else
{
logInfo("set signal success...");
}
/* set time interval */
struct itimerval stItimerVal;
stItimerVal.it_value.tv_sec = 60;
stItimerVal.it_value.tv_usec = 0;
stItimerVal.it_interval = stItimerVal.it_value;
iRet = setitimer(ITIMER_REAL, &stItimerVal, NULL);
if(0 != iRet)
{
logError("set timer failed...");
return -1;
}
logInfo("OS_StartTrigger end...");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
看起来 Go 存储库中有一个测试可以满足您的需求。测试的工作原理如下:main.c旨在测试所有发行版的 cgo 中的信号处理。查看 unix 发行版 ( main_unix.c ) 的处理程序,您会得到:
int install_handler() {
// Install our own signal handler.
memset(&sa, 0, sizeof sa);
sa.sa_sigaction = handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_ONSTACK | SA_SIGINFO;
memset(&osa, 0, sizeof osa);
sigemptyset(&osa.sa_mask);
if (sigaction(SIGSEGV, &sa, &osa) < 0) {
perror("sigaction");
return 2;
}
if (osa.sa_handler == SIG_DFL) {
fprintf(stderr, "Go runtime did not install signal handler\n");
return 2;
}
// gccgo does not set SA_ONSTACK for SIGSEGV.
if (getenv("GCCGO") == NULL && (osa.sa_flags&SA_ONSTACK) == 0) {
fprintf(stderr, "Go runtime did not install signal handler\n");
return 2;
}
oldHandler = osa.sa_sigaction;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
现在测试正在向 中添加处理程序SIGSEGV,因此请将其替换为有问题的信号。