简体   繁体   中英

Does the abort() function in C clean the stack?

It's possible to catch the SIGABRT and continue the program with a longjump for example.

I wonder if this can lead to a stack overflow when I always call functions that invoke abort().

I need to know that because i want to use the assert macro (taht calls abort) in unit tests. If an assert fails, I want to continue with the next unit test.

abort doesn't need to clear the stack; longjmp will "clear" it in that it will rewind the stack pointer back to the position of setjmp . If all else is correct, repeatedly invoking longjmp and setjmp will not cause stack overflow.

However, longjmp will skip normal execution path, which can call resource leaks in its own right. Consider this code:

char *s = malloc(...);
... use s ...
free(s);

If the "... use s ..." portion calls some function that longjmp s out of the code, free won't get a chance to get called and you will leak. The same applies to closing open files, sockets, freeing shared memory segments, reaping forked children, and so on.

For this reason longjmp is rarely used in C programming. My advice would be to avoid assert if you don't mean the program to exit. Simply use another macro in your unit tests, or switch to a testing framework that provides one.

longjmp does not unwind the stack, but it does modify the stack pointer:

If the function in which setjmp was called returns, it is no longer possible to safely use longjmp with the corresponding jmp_buf object. This is because the stack frame is invalidated when the function returns. Calling longjmp restores the stack pointer , which—because the function returned—would point to a non-existent and potentially overwritten/corrupted stack frame.

Assuming POSIX, calling longjmp to get out of the SIGABRT raised by abort is valid, because abort is specified to be async-signal-safe (and also because this signal is not asynchronous). (In plain C, doing almost anything from a signal handler is UB so it's usually not an interesting case to talk about.) However, it's your responsibility to make sure that none of your own program's state is left inconsistent as a result, in such a way that it would cause your program to invoke UB in some other way immediately or much later in the program flow.

With that said, I agree with user4815162342 that your proposal is a very bad form of error handling. If you don't want to abort, don't call abort , but instead write your own error handling functions.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM