【问题标题】:How to get further information on SIGFPE signal?如何获得有关 SIGFPE 信号的更多信息?
【发布时间】:2015-06-03 18:44:14
【问题描述】:

来自GNU C 库参考手册

int SIGFPE

SIGFPE 信号报告一个致命的算术错误。这个信号 实际上涵盖了所有算术错误,包括除以零和 溢出。

BSD 系统为 SIGFPE 处理程序提供了一个额外的参数 区分异常的各种原因。为了访问 这个参数,你必须定义处理程序来接受两个参数, 这意味着您必须将其转换为单参数函数类型 建立处理程序。

但没有关于如何访问额外参数的示例。

我做了我的谷歌工作,但找不到任何东西。

如何获得这些额外信息?

【问题讨论】:

  • 访问任何函数参数的方式相同——通过您为形式参数提供的名称。
  • @BenVoigt 抱歉,我对系统编程和 C 语言不是很有经验。你的评论是什么意思?
  • 为什么不使用sigaction() 而不是过时的signal(),并享受获得struct siginfo* 的乐趣呢?
  • @RossRidge 修复了标签,抱歉。
  • @KorayTugay:每个 C 程序都以 int main(int argc, char** argv) 开头,您可以通过名称 argcargv 访问参数。当你创建一个函数来处理你的信号时,你将为参数命名。

标签: c unix signals posix bsd


【解决方案1】:

正如 cmets 中提到的 EOF,更好的方法是使用 sigactionSA_SIGINFO 标志安装信号处理程序,不需要正式破坏强制转换,并且正确记录了奖励,然后在第二个参数的si_code字段中(输入siginfo_t)就可以判断发生了哪个浮点错误:

对于SIGFPE 信号,可以将以下值放入si_code

FPE_INTDIV 整数除以零。

FPE_INTOVF 整数溢出。

FPE_FLTDIV 浮点除以零。

FPE_FLTOVF 浮点溢出。

FPE_FLTUND 浮点下溢。

FPE_FLTRES 浮点不精确结果。

FPE_FLTINV 浮点数无效操作。

FPE_FLTSUB 下标超出范围。

来源:Linux sigaction(2) man page

FreeBSD siginfo man page 上也有同样的列表。

【讨论】:

【解决方案2】:

glibc 引用的信息是历史机制,不可移植。在 FreeBSD 上,sigvec(2) 手册页包含一个符号,表明它仅在 VAX-11 架构上受支持:

在 VAX-11 上可以声明处理程序:

void  handler(sig, code, scp)
int sig, code;
struct sigcontext *scp;

这里的 sig 是信号编号,硬件故障和陷阱进入其中 映射如下定义。代码参数是常量 下面给出,或者,对于兼容模式错误,由 硬件(兼容模式故障区别于其他 SIGILL 通过在 psl 中设置 PSL_CM 进行陷阱)。 scp 参数是 指向 sigcontext 结构的指针(在<signal.h> 中定义),用于 从信号之前恢复上下文。

此版本的手册页中实际上并未提供映射列表。它可以在4.3BSD-Reno signal(3) manpage 中找到。值得注意的是,这篇文字已有 25 年历史。

在现代系统上,您应该使用 sigaction 机制,它的定义更加明确且可移植。

BUGS - 本手册页仍然令人困惑。

确实如此。

【讨论】:

    猜你喜欢
    • 2012-06-17
    • 1970-01-01
    • 1970-01-01
    • 2020-04-24
    • 1970-01-01
    • 1970-01-01
    • 2016-01-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多