【问题标题】:Is there a way to test whether I'm in a signal handler?有没有办法测试我是否在信号处理程序中?
【发布时间】:2011-01-24 07:09:55
【问题描述】:

我必须处理一个可以从大型项目中的不同位置调用的日志记录模块。我遇到的问题是,有时模块可能会从信号处理程序内执行的代码中调用。通常,日志记录模块使用 localtime() 和 strftime() 包含时间数据,但是这些调用当然不是异步信号安全的,如果从信号处理程序中调用可能会导致死锁。有没有办法(在 GNU/Linux 系统上)判断我的代码当前是否在信号处理程序上下文中执行,除了例如让每个信号处理程序在处理时设置一个标志?我认为简化我们的信号处理程序会更好,但在这种情况下,我无法选择调用日志模块的位置。如果我可以测试并在信号处理期间调用模块时省略时间戳信息,那就太好了。

【问题讨论】:

  • 从信号处理程序进行系统调用通常是个坏主意...你确定你在这里受到保护吗?
  • 是的,这就是问题所在。我想避免不安全的系统调用如果我在信号处理程序中,但如果在我不在信号处理程序中时调用代码,则它们可用。

标签: c signals signal-handling async-safe


【解决方案1】:

你的系统有sigpending吗?我不知道该函数在信号处理程序期间的行为是什么。但是,如果它返回一个设置标志,您可能会很悲观,如果有任何信号未决,您可能会跳过异步不安全调用。

【讨论】:

  • 我认为 sigpending 仅在信号传递之前设置。输入信号处理程序后,信号不会设置为“待处理”。
【解决方案2】:

首先,您的问题(“我在信号处理程序中吗?”)没有明确的答案。考虑以下代码:

#include <setjmp.h>
#include <signal.h>

jmp_buf jb;
int foo(int s)
{
    longjmp(jb,1);
}

int main()
{
    if (setjmp(jb)) {
        puts("Am I in a signal handler now, or not?");
        return 0;
    }
    signal(SIGINT, foo);
    raise(SIGINT);
}

话虽如此,您可以使用一种技术以对许多程序有意义的方式回答这个问题。选择一个您不打算使用的信号,并将其添加到您处理的所有信号的sa_mask,使用sigaction 安装信号处理程序。然后你可以使用sigprocmask查看当前的信号掩码,如果你指定的信号在信号掩码中,说明有一个信号处理函数已经被调用,还没有返回(返回会恢复原来的信号掩码)。

【讨论】:

  • 这是关于longjmp(或siglongjmp)的一个有趣点;我将不得不考虑这一点以及在信号处理程序中的实际含义。我主要关心的是知道我是否可以在可能持有锁的代码的其他部分中,并且由于这种事情无论如何都不会是 setjmp/longjmp 安全的,所以我并没有真正在任何地方使用 jmp 函数他们可能会导致这个问题。不过,我喜欢 sigaction/sa_mask 建议,这听起来基本上正是我正在寻找的。​​span>
【解决方案3】:

最简单的方法是通过(命名)管道(写入到 PIPE_MAX 是原子的)或通过 UDP 套接字(同上)记录。消息来源可以由生成消息的函数设置。当然,您需要一个实际读取和处理消息的进程,但它可以保留在信号处理程序的上下文之外。


顺便说一句:您不需要单独的进程来接收消息,您可以将消息发送到您自己的进程并将管道(的读取端)添加到 fd_set(假设您的程序位于 select 或 poll循环),或定期轮询。

【讨论】:

  • 另外,您尝试做的事情是不正当的。您不会从信号处理程序中跳转(参见 sigjump 等)。此外,stdio 函数不被认为是信号安全的(它们可能会调用 malloc() 等)
  • 糟糕,我评论了 R. 的程序,这应该是不正当的。对不起!
  • 我喜欢这个答案,因为它提供了一种做事的好方法,但我真的不想添加一个单独的进程并通过管道发送所有日志消息,如果我不需要的话.我仍然希望有一种简单的方法来检测我是否在信号处理程序中;看起来操作系统应该不难知道。
  • 您可以将消息发送到您自己的进程并将管道添加到 fd_set(假设您处于选择或轮询循环中)
猜你喜欢
  • 1970-01-01
  • 2016-11-13
  • 2021-12-25
  • 2017-12-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-03
  • 2013-06-19
相关资源
最近更新 更多