【问题标题】:C Program, Pass Arguments into Signal Handler Function?C程序,将参数传递给信号处理函数?
【发布时间】:2019-01-22 20:48:16
【问题描述】:

我有一个可能的“无法完成!”问题,我想从社区中反弹。

我正在使用 C 语言编写的 libIPFIX 程序。在代码的开头,该程序设置了一个 Signal Handler 函数:

void exit_func ( int signo )
{
    if ( verbose_level && signo )
        fprintf( stderr, "\n[%s] got signo %d, bye.\n\n", progname, signo );

    ...clean up global variables...

    exit( 1 );
}

稍后在 main() 中,信号处理程序被连接到更大的代码中:

int main (int argc, char *argv[])
{
    ...

    // signal handler
    signal( SIGKILL, exit_func );
    signal( SIGTERM, exit_func );
    signal( SIGINT,  exit_func );

    ...

    exit(1);
}

据我所知,漂亮的样板。

这是我的问题:我正在使用 malloc() 和链表之类的修改版本的程序跟踪大量额外数据。当代码检测到信号时,如果exit_func() 可以调用我的 cleanup() 函数来消除内存泄漏,那就太好了,等等。我喜欢的是这个:

void exit_func ( int signo, LLNode* myData )
{
    ...same...

    cleanUp( myData );

    exit( 1 );
}

但是阅读sigaction 加上像these 这样的帖子加上我自己的实验强烈表明没有办法将额外的参数传递给exit_func()。做我想做的事情的唯一方法就是把我的数据变成一个全局变量。出于其他设计原因,我真的很讨厌这样做。

所以我想我会破产并只是问:有没有办法将参数传递给exit_func()?提前致谢。

【问题讨论】:

  • OT:如果程序仍然终止,为什么还要关心内存泄漏?
  • @4386427 - 好问题。我不知道,我正在尝试坚持最佳实践,并且总是释放我分配的内存。没有其他原因。
  • 我无法回答您的明确问题,但据我所知,您无需担心内存泄漏,因为任何现代操作系统都会在程序终止时为您处理“清理”。
  • 如果内存真的泄漏了,你无论如何都不能释放它。此外,在信号处理程序中使用 stdio 函数也不安全。这种方式存在未定义的行为。
  • @Pete 这实际上是一种不好的做法。您只是在减慢您的程序并增加维护开销。

标签: c parameter-passing signals


【解决方案1】:

您不能将参数发送到信号处理程序。需要从处理程序访问的任何内容都需要放入某种全局结构中。

【讨论】:

  • 哇,谢谢鲍勃。不是我希望的答案,而是我需要的信息。非常感谢...!
  • 是的。没什么好说的了。它只能到达全局变量,并且只接收信号编号。我发现如果我可能需要访问不止一个东西,通常最好只用指向我需要的指针填充一个(全局)结构。
【解决方案2】:

您的原始代码已经错误(即使它看起来有效;它仍然是undefined behavior)。首先阅读signal (IPC) wikipage。

原来的信号处理程序exit_func 已经错了。阅读signal(7)signal-safety(7)exitfprintf 都不能被调用,即使是从信号处理程序间接调用,因为它们不是 async-signal-safemalloc 也不是)。

您最好在信号处理程序中设置一些volatile sig_atomic_t 变量,并在事件循环中对其进行测试(请参阅thisPOSIX documentation on signal.h)。这是通常的做法(一旦你这样做了,你必须这样做以符合 signal(7)signal-safety(7) 规则,你的问题就变得无关紧要了)。

您可能对 Linux 特定的 signalfd(2) 感兴趣(它有一些小缺陷。STFW 适合他们)。

Qt 文档中有一个很好的章节Calling Qt functions from Unix signal handlers。那里的一些智慧(例如pipe(7) to self 技巧)可能适用于您的程序,即使它不使用 Qt。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-21
    • 1970-01-01
    • 1970-01-01
    • 2015-01-30
    • 2017-12-30
    • 2012-08-30
    相关资源
    最近更新 更多