gdb是否更改处理程序线程中sigwait捕获的sigint值?
我有一个多线程(pthreads)应用程序,其中我钩住了gdb是否更改处理程序线程中sigwait捕获的sigint值?,gdb,pthreads,signals,Gdb,Pthreads,Signals,我有一个多线程(pthreads)应用程序,其中我钩住了SIGINT,允许我中断程序。我设置了一个信号处理器线程,如下所示: /*** startup code ***/ // Prep signal-related stuff: signal(SIGPIPE, SIG_IGN); sigset_t set; sigemptyset(&set); sigaddset(&set, SIGINT); assert(0 == pthread_sigmask(SIG_BLOCK
SIGINT
,允许我中断程序。我设置了一个信号处理器线程,如下所示:
/*** startup code ***/
// Prep signal-related stuff:
signal(SIGPIPE, SIG_IGN);
sigset_t set;
sigemptyset(&set);
sigaddset(&set, SIGINT);
assert(0 == pthread_sigmask(SIG_BLOCK, &set, NULL));
// Spawn signal handling thread
pthread_t sig_pthread;
pthread_create(&sig_pthread, NULL, &sig_thread, (void *) &set);
信号处理程序线程如下所示:
static void* sig_thread(void *arg) {
sigset_t *set = (sigset_t *) arg;
int s, sig;
#ifndef __APPLE__
prctl(PR_SET_NAME, "signal hander", 0, 0, 0);
#endif
for (;;) {
s = sigwait(set, &sig);
if (s != 0) {
ERR(E_UNKNOWN, "sigwait failed?\n");
/* ERR is macro -> exit(E_UNKNOWN) */
}
if (sig == SIGINT) {
...
} else {
ERR(E_UNKNOWN, "caught unknown signal %d\n", sig);
/* ERR is macro -> exit(E_UNKNOWN) */
}
}
}
正常运行时,代码按预期工作。但是,如果我在gdb下运行该程序,我会得到:
--E:捕获未知信号4611
有人对(十进制)值4611(0x12030103)有什么见解吗?在
signal.h
中没有任何明显的变化。有人知道gdb在做什么导致这种情况发生,以及我如何修复/防止它吗?我怀疑4611
是垃圾,因为您在调用sigwait()
之前没有初始化sig
从您显示的源代码来看,如果出现错误(s!=0
),您似乎不会跳过对sig
的测试
您可能希望对代码进行如下修改:
#include <stdio.h>
#include <signal.h>
...
#define E_UNKNOWN "E"
#define ERR(ec, fmt, ...) (fprintf(stderr, "--- %s: " fmt, (ec), __VA_ARGS__))
...
for (;;) {
int sig = 0;
int s = sigwait(set, &sig);
if (s != 0) {
ERR(E_UNKNOWN, "sigwait() failed with %d.\n", s);
}
else {
if (sig == SIGINT) {
...
} else {
ERR(E_UNKNOWN, "Caught unhandled signal %d.\n", sig);
}
}
...
#包括
#包括
...
#定义E_未知的“E”
#定义错误(ec,fmt,…)(fprintf(标准,“--%s:”fmt,(ec),\uu VA\u ARGS)
...
对于(;;){
int-sig=0;
int s=sigwait(set,&sig);
如果(s!=0){
错误(E_未知,“sigwait()失败,出现%d。\n”,s);
}
否则{
if(sig==SIGINT){
...
}否则{
错误(E_未知,“捕获到未处理的信号%d.\n”,sig);
}
}
...
我怀疑4611
是垃圾,因为您在调用sigwait()
之前没有初始化sig
从您显示的源代码来看,如果出现错误(s!=0
),您似乎不会跳过对sig
的测试
您可能希望对代码进行如下修改:
#include <stdio.h>
#include <signal.h>
...
#define E_UNKNOWN "E"
#define ERR(ec, fmt, ...) (fprintf(stderr, "--- %s: " fmt, (ec), __VA_ARGS__))
...
for (;;) {
int sig = 0;
int s = sigwait(set, &sig);
if (s != 0) {
ERR(E_UNKNOWN, "sigwait() failed with %d.\n", s);
}
else {
if (sig == SIGINT) {
...
} else {
ERR(E_UNKNOWN, "Caught unhandled signal %d.\n", sig);
}
}
...
#包括
#包括
...
#定义E_未知的“E”
#定义错误(ec,fmt,…)(fprintf(标准,“--%s:”fmt,(ec),\uu VA\u ARGS)
...
对于(;;){
int-sig=0;
int s=sigwait(set,&sig);
如果(s!=0){
错误(E_未知,“sigwait()失败,出现%d。\n”,s);
}
否则{
if(sig==SIGINT){
...
}否则{
错误(E_未知,“捕获到未处理的信号%d.\n”,sig);
}
}
...
包含`/***启动代码***/`的代码,在sig_thread()线程运行时,此线程/函数/等是否仍然存在-只是为了确保将设置
变量交给sig_thread())仍然存在并且不是垃圾?是的,它为进程的生命而存在。我认为这可能不是gdb本身正在做的事情,而是一个内核和/或libc问题。如果我正在研究这个问题,我可能会尝试使用systemtap在这里观察内核行为。包含`/***启动代码***/`的代码,这个线程/函数/etc.stsig_thread()线程正在运行时将不存在-只是为了确保将set
变量交给sig_thread()仍然存在并且不是垃圾?是的,它为进程的生命而存在。我认为这可能不是gdb本身正在做的事情,而是一个内核和/或libc问题。如果我正在研究这个问题,我可能会尝试使用systemtap在这里观察内核行为。但是它永远不会到达那里。ERR
是一个扩展到exit()
带有一些漂亮的打印。如果s!=0
代码将在到达未处理的信号线之前消失。我编辑了这个问题以使其更清楚一些。@Pat:我明白了。但是,在调用sigwait()
之前,您可以先初始化sig
,因为您将看到sigwat()
设置4611
与否。但是,它不应该到达那里。ERR
是一个扩展到exit()的宏
有一些漂亮的打印。如果s!=0
代码将在到达未处理的信号线之前消失。我编辑了这个问题以使其更清楚一些。@Pat:我明白了。但是,您可以在调用sigwait()
之前先初始化sig
,因为您将看到sigwat()
是否设置4611
。