gdb是否更改处理程序线程中sigwait捕获的sigint值?

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

我有一个多线程(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, &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