【问题标题】:seg fault, bus error, abort段故障,总线错误,中止
【发布时间】:2017-10-26 20:24:33
【问题描述】:

我正在尝试重现 std libc funcs 的行为。 阳性病例 - 好的。 负面案例 - 好的。 但... 我所有的负面案例都给了我“seg fault”而不是“bus err”/“abort”。

例子:

void func()
{
    ...
    char    str[3] = "nvm";
    char    str2[3] = "nbd";
    my_strcat(str, str2);
    ...
}

robot$> 分段错误./ex

void    func()
{
    ...
    char    str[3] = "nvm";
    char    str2[3] = "nbd";
    strcat(str, str2);
    ...
}

机器人 $> 中止 ./ex

那么“段错误”和“中止”有什么区别?我怎样才能“中止”我的代码?

【问题讨论】:

  • 查找重复项:修改字符串文字。更糟糕的是,没有足够的内存来允许strcat。两个特定错误 - 它们不应该是指针数组,而是 char 数组,并且 [size] 限制阻止编译器自动添加 '\0' 字符串终止符,因此任何字符串处理函数都会失败。
  • 您更改了代码。请发布 实际 代码,不要更改它以使 cmets 或答案无关紧要。请阅读Minimal, Complete, and Verifiable example - 这不是一个动态代码模组网站。
  • 我的错,字符数组。但我无论如何都在谈论崩溃行为。为什么 libc func 给我“中止”而 libmy func 给我“seg fault”?
  • 您正在调用未定义的行为。如果 C 提供了一种控制或预测结果的方法,那么将改为定义行为。

标签: c crash crash-reports abort


【解决方案1】:

“我如何'中止'我的代码”有一个简单的答案:调用函数abort,在stdlib.h 中定义。

“Why [does] libc func [give] me 'abort' and libmy func [give] me 'seg fault'”也有一个直截了当的答案:在这两种情况下,您都在要求库函数执行无效操作; C 库有代码来检测这个特定的无效操作本身,并调用abort;您的代码不会尝试检测错误,而是 硬件 将其捕获为“内存保护”违规,这会导致操作系统生成致命的“分段错误”信号。

不能告诉你的是如何让“libmy func”做 C 库所做的事情,因为在 ISO C 或 POSIX 中都没有办法做到这一点。 (在 Win32 中可能有一种方法,但我不知道它是什么,而且无论如何,如果您使用的是 Windows,您就不会谈论分段错误。)我实际上认为 C 库 不应该 这样做,因为这里的原因太复杂了,C 库所做的检查不可能准确,即使是 POSIX 以外的操作系统扩展;更好的是,它应该把工作留给内存保护硬件,在那里它至少可以是健全的(没有误报)。

顺便说一句,多年来“分段错误”(SIGSEGV)和“总线错误”(SIGBUS)之间没有任何有意义的区别;应用程序代码应该将它们视为等效的,如果它需要尝试从中恢复(大多数代码甚至不应该尝试),应该对这两种情况使用相同的恢复代码。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-05-11
    • 2011-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-02
    • 1970-01-01
    相关资源
    最近更新 更多