Search code examples
ccrashcrash-reportsabort

seg fault, bus error, abort


I'm trying to reproduce behavior of std libc funcs. Positive cases - OK. Negative cases - OK. But... All of my negative cases gives me "seg fault" instead of "bus err"/"abort".

Example:

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

robot$> segmentation fault ./ex

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

robot $> abort ./ex

So what diff "seg fault" and "abort"? And how can i "abort" my code?


Solution

  • "How can I 'abort' my code" has an easy answer: call the function abort, defined in stdlib.h.

    "Why [does] libc func [give] me 'abort' and libmy func [give] me 'seg fault'" also has a straightforward answer: in both cases, you are asking the library function to perform an invalid operation; the C library has code to detect this particular invalid operation itself, and calls abort; your code doesn't try to detect the error, so instead the hardware traps it as a "memory protection" violation, which causes the operating system to generate a lethal "segmentation fault" signal.

    What I can't tell you is how to make "libmy func" do what the C library does, because there is no way to do that in either ISO C nor in POSIX. (There might be a way in Win32 but I don't know what it is, and anyway if you were using Windows you wouldn't be talking about segmentation faults.) I would actually argue that the C library shouldn't do that, because for reasons too complicated to go into here, it's not possible for a check done by the C library, even with operating system extensions beyond POSIX, to be accurate; better it should leave the job to the memory-protection hardware, where it can at least be sound (no false positives).

    Incidentally, there hasn't been any meaningful difference between "segmentation fault" (SIGSEGV) and "bus error" (SIGBUS) in many years; application code should treat them as equivalent, and if it needs to attempt to recover from either (most code shouldn't even try), should use the same recovery code for both cases.