段故障、总线错误、中止
seg fault, bus error, abort
我正在尝试重现 std libc 函数的行为。
阳性病例 - 好的。
负面案例 - 好的。
但...
我所有的负面案例都给我 "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
那么 "seg fault" 和 "abort" 有什么区别?我如何 "abort" 我的代码?
"How can I 'abort' my code" 有一个简单的答案:调用定义在 stdlib.h
.
中的函数 abort
"Why [does] libc func [give] me 'abort' and libmy func [give] me 'seg fault'"也有一个直截了当的答案:在这两种情况下,你都在要求库函数执行无效操作; C 库本身有代码来检测这个特定的无效操作,并调用 abort
;您的代码不会尝试检测错误,因此 硬件 将其捕获为 "memory protection" 违规,这会导致操作系统生成致命的 "segmentation fault"信号。
我不能告诉你的是如何让"libmy func"做C库做的事情,因为在ISO C中没有办法做到这一点也不在 POSIX 中。 (在 Win32 中可能有一种方法,但我不知道它是什么,无论如何,如果你使用 Windows 你就不会谈论分段错误。)我实际上认为 C 库 不应该 这样做,因为由于太复杂的原因无法进入这里,即使操作系统扩展超过 POSIX,也不可能由 C 库完成检查准确的;最好把工作留给内存保护硬件,在那里它至少可以是可靠的(没有误报)。
顺便说一句,多年来 "segmentation fault" (SIGSEGV) 和 "bus error" (SIGBUS) 之间没有任何有意义的区别;应用程序代码应将它们视为等同的,并且如果它需要尝试从其中任何一个中恢复(大多数代码甚至不应该尝试),则应为这两种情况使用相同的恢复代码。
我正在尝试重现 std libc 函数的行为。 阳性病例 - 好的。 负面案例 - 好的。 但... 我所有的负面案例都给我 "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
那么 "seg fault" 和 "abort" 有什么区别?我如何 "abort" 我的代码?
"How can I 'abort' my code" 有一个简单的答案:调用定义在 stdlib.h
.
abort
"Why [does] libc func [give] me 'abort' and libmy func [give] me 'seg fault'"也有一个直截了当的答案:在这两种情况下,你都在要求库函数执行无效操作; C 库本身有代码来检测这个特定的无效操作,并调用 abort
;您的代码不会尝试检测错误,因此 硬件 将其捕获为 "memory protection" 违规,这会导致操作系统生成致命的 "segmentation fault"信号。
我不能告诉你的是如何让"libmy func"做C库做的事情,因为在ISO C中没有办法做到这一点也不在 POSIX 中。 (在 Win32 中可能有一种方法,但我不知道它是什么,无论如何,如果你使用 Windows 你就不会谈论分段错误。)我实际上认为 C 库 不应该 这样做,因为由于太复杂的原因无法进入这里,即使操作系统扩展超过 POSIX,也不可能由 C 库完成检查准确的;最好把工作留给内存保护硬件,在那里它至少可以是可靠的(没有误报)。
顺便说一句,多年来 "segmentation fault" (SIGSEGV) 和 "bus error" (SIGBUS) 之间没有任何有意义的区别;应用程序代码应将它们视为等同的,并且如果它需要尝试从其中任何一个中恢复(大多数代码甚至不应该尝试),则应为这两种情况使用相同的恢复代码。