【问题标题】:Determine if a function is async-signal-safe (can be called inside a signal handler)确定一个函数是否是异步信号安全的(可以在信号处理程序中调用)
【发布时间】:2012-01-26 06:16:09
【问题描述】:

我的问题是:

  1. 如果您无权访问函数的实现,是否有办法最终确定函数是否是异步信号安全的?
  2. 如果不是,有没有办法测试函数是否足够异步信号安全以从信号处理程序调用?

如果您阅读 signal() 或 sigaction() 的手册页,您会得到一个异步信号安全函数列表(可以在信号处理程序中安全调用的函数)。但是,我相信这份清单并不详尽。例如,以下页面 http://linux.die.net/man/7/signal,在 Async-signal-safe functions 标题下,内容如下:

POSIX.1-2004(也称为 POSIX.1-2001 Technical Corrigendum 2)需要一个实现来保证可以在信号处理程序中安全地调用以下函数:

然后它继续列出上面手册页中列出的正常异步信号安全函数。当我读到它时,它说的是“它需要”,而不是“这些是唯一的”。

例如,this site 表示 back_trace_symbols_fd() 是异步信号安全的。该函数获取的是来自 dladdr() 的数据,它不像 back_trace_symbols() 那样使用 malloc(),所以看起来它可能是安全的。另外,我做了一些测试,dladdr() 的输出结构包含 char* 变量,但这些变量在运行时不是 malloc 的。它们指向的 char 字符串甚至在调用 dladdr() 之前就存在于运行时。

感谢任何可以为我指明正确方向的想法或想法。

【问题讨论】:

  • 不要忘记为您的问题投票有用的答案,或者接受对您的每个问题最有用的答案。如果您不确定,请查看FAQ,尤其是How do I ask questions here?

标签: objective-c c posix signals


【解决方案1】:

如果您无权访问该函数的实现,可以查看手册页。如果手册页没有说它是异步安全的,而 POSIX 标准也没有说它是异步安全的,那么唯一安全的结论是“它不是异步安全的”(加上“不要使用它” )。

没有 100% 可靠的方法来测试函数是否是异步安全的。请记住,测试只能显示错误的存在,而不是它们的缺失 (Dijkstra)。您没有设法让功能在测试中表现不佳这一事实可能仅仅意味着您的测试不充分(但请放心,您不能冒犯的重要客户会立即意外地设计出一种毁灭性的有效方法几乎在您发布带有错误假设的代码时就证明该函数不是异步安全的测试)。

【讨论】:

  • 这种方法相当令人沮丧,因为例如 strlenmemcpy 不能保证异步信号安全。但你只需要忍受它——你永远不知道什么时候会有一些明亮的火花会发明一个经过优化的memcpy,它真的不会重入。无论如何,C 标准说库函数通常根本不能从信号处理程序调用(async-signal-unsafe 只是说它不能从一个信号处理程序调用它恰好中断另一个不安全函数,但这是一个很难真正从中获得任何优势)。
  • @SteveJessop strlen() 在 sigaction() 的手册页中未定义为异步信号安全,但您可以实现自己的异步信号安全版本。它所做的只是计算非 NULL 字符,并在达到 NULL 时返回该值。
  • @JonathanLeffler 你知道为什么有些手册页指定线程安全和信号安全,而有些则没有吗?我猜我应该遵循我自己操作系统的手册页。一些手册页指定了一个 attributes(5) 函数(不确定它是否是一个函数),它指定了所有这些以及更多。你知道如何访问它吗?请参阅示例手册页:compute.cnr.berkeley.edu/cgi-bin/man-cgi?dladdr+3
  • 要访问attributes(5),请使用man 5 attributesman -s 5 attributes。有些手册页写得比其他的更仔细。
【解决方案2】:

您希望在信号处理程序中实现什么?你应该考虑它是否适合它。最好遵循手册页的建议:

In general, signal handlers should do little more  
than set a flag; most other actions are not safe.

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2016-03-31
  • 1970-01-01
  • 2019-07-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多