gcc / Linux : hook exit() call to prevent exit from happening
I have a pretty unique case where I am calling a 3rd party library (which I cannot modify) from a higher-level C program. This code has a clean-up routine that calls exit() — which terminates the whole application. However, I do not want to terminate the whole application at this time, as there is still some work that must be done by the main application. So to solve this, I tried to ‘trick’ this 3rd party library by temporarily ‘aliasing’ the exit() function call to a dummy function using dlsym — and then later restoring exit() to its normal state. This solution almost works — using LD_PRELOAD to point to the dummy exit wrapper I can see this dummy exit function being called — however, imminently after this I get a segmentation fault when this function goes out of scope. I suspect this has to do with the fact that gcc by default puts an attribute called noreturn on this function. Is there a way to remove this noreturn attribite, or better still another way of preventing this 3rd party library from calling exit()? Any and all suggestions would be most appreciated.
If this is threaded: Let the exit() replacement call pause() and when done send it a signal to have pause() return and call the real exit() ?
«as there is still some work that must be done by the main application.» would perhaps atexit() help you?
Even if you could, it’s a phenomenally bad idea to try to trick code that thinks it’s calling exit() into calling something else instead. If you need to perform your own cleanup, then either do it before calling the library routine, or register an exit handler as @alk suggested. If you don’t want to exit at all, then don’t call that library function at that time.
Also, it is . rude . for a library function to call exit() in the first place, at least if there is no alternative that avoids exiting. Especially so if the library insists that programs that use it exit that way — consider that no one program can use two such libraries. If it were me, I’d be looking into dumping the library altogether.
@alk thanks a lot — atexit seems to be doing the trick. I changed the previous routine calling the cleanup function to now use atexit to register the call to the cleanup function. So now only when the main application exits the pesky cleanup function is called then.
What is the difference between exit() and abort()?
In C and C++, what is the difference between exit() and abort() ? I am trying to end my program after an error (not an exception).
5 Answers 5
abort() exits your program without calling functions registered using atexit() first, and without calling objects’ destructors first. exit() does both before exiting your program. It does not call destructors for automatic objects though. So
Will destruct a and b properly, but will not call destructors of c . abort() wouldn’t call destructors of neither objects. As this is unfortunate, the C++ Standard describes an alternative mechanism which ensures properly termination:
Objects with automatic storage duration are all destroyed in a program whose function main() contains no automatic objects and executes the call to exit() . Control can be transferred directly to such a main() by throwing an exception that is caught in main() .
struct exit_exception < int c; exit_exception(int c):c(c) < >>; int main() < try < // put all code in here >catch(exit_exception& e) < exit(e.c); >>
Instead of calling exit() , arrange that code throw exit_exception(exit_code); instead.
+1 because, while Brian R. Bondy was good, you did raise the problem of abort/exit (not destructor of stack objects called), and offered the alternative for a RAII-intensive C++ process.
I was looking on a way to quit a program without calling dtor and your answer is just what i was looking for! Thanks
That is perfectly correct of course, if it actually matters that your automatic objects destructors are not called 🙂
To my knowledge, one further difference between exit and abort would be, that abort could (depending on the operating system configuration) lead to the generation of a core dump.
abort sends a SIGABRT signal, exit just closes the application performing normal cleanup.
You can handle an abort signal however you want, but the default behavior is to close the application as well with an error code.
abort will not perform object destruction of your static and global members, but exit will.
Of course though when the application is completely closed the operating system will free up any unfreed memory and other resources.
In both abort and exit program termination (assuming you didn’t override the default behavior), the return code will be returned to the parent process that started your application.
See the following example:
SomeClassType someobject; void myProgramIsTerminating1(void) < coutvoid myProgramIsTerminating2(void) < coutint main(int argc, char**argv) < atexit (myProgramIsTerminating1); atexit (myProgramIsTerminating2); //abort(); return 0; >
- If abort is uncommented: nothing is printed and the destructor of someobject will not be called.
- If abort is commented like above: someobject destructor will be called you will get the following output:
Exit Function in C
Exit() is a core function in the C/C++ programming language that is used to instantly end the calling process (function). It is possible to call from any function. It informs the operating system of the state of program termination by passing an int value. It is usually used when software crashes unexpectedly. It is also recognized as the program’s current state. The exit function can be used to end a program at any moment, regardless of how many function calls have been performed. It calls a variety of other functions before terminating the application, such as shutting open files, to clean up.
The exit function is specified in the header and is included in the C standard libraries. The file defines several types, macros, and basic utility functions for performing numerical conversions, random number generation, sorting, memory management, and interacting with the environment. To interrelate with the environment, utilize the exit function.
Parameters
Parameters of exit() function in the C programming language are described underneath.
EXIT_SUCCESS
If the passed status argument is zero or the int valued macro: EXIT_SUCCESS, described in the header, a successful status should be passed to the host environment, and thus an execution defined form of the successful status is brought back to the hosting environment, toward whom control is conceded. Exit(0) is used to generally terminate a program by indicating that the operation was accomplished. EXIT_SUCCESS has a value of 0.
As a result, rather than exit, we could use exit(EXIT_SUCCESS). EXIT_SUCCESS is a prefix that extends into integer expressions that can be passed to the method exit as an argument. And exit(0) signifies a clean exit from the program with no errors.
EXIT_FAILURE
If the supplied status argument is the int-valued macro EXIT_FAILURE, specified in the header, the exit function will return an execution version of the failure result to the hosting environment, to which control is specified. It can also be used to end the program normally but with the condition that the operation failed. EXIT_FAILURE has a value of 1.
As a result, rather than exit, we can use exit EXIT_FAILURE. EXIT_FAILURE is a phrase that can be used for a range of purposes. Exit status 1 represents that there was a runtime issue, which could have been caused by a programming error.
Example 1
We have an example to illustrate the basic functionality of the exit() function in the C programming language. Make a file in your GCC compiler that is configured in your Windows 10 system. The file name can be dependent on your choice but its extension must be “.c”. At the start of our program, few libraries have been added for the smooth execution of code. After that, we have the main function. Initially, we have used two printf() statements with “\n” specifier that will print their result in two separate lines.
After these two statements, exit(0) has been called. The functionality of exit(0) has been explained in detail in the parameters segment of this guide. After this function call, another print statement has been used but it will not be displayed on the output screen. The reason for this implementation is that exit(0) has been used before the third statement. Now, save and close the file to get the result of your program.
As soon as you save the file, you have to compile and run your example code, as rapidly as you hit the “Run and Compile” option of your GCC compiler, the console will pop up on your screen which exhibits the expected result.
Example 2
Now, we are moving towards our second example to demonstrate the simple functionality of the exit() function in the C programming language. Again, build a file in your GCC compiler that is configured in your Windows 10 system or utilize the former one by clearing the previous code. The file name can be reliant on your choice but its extension must be “.c”. At the start of our program, few libraries have been introduced for the smooth implementation of code. After that, we have the main function. Initially, we have used one printf() statement.
After this statement, exit(0) has been called. It will just terminate the program here without moving further. The functionality of exit(0) has been clarified in detail in the parameters section of this guide. After this function call, another print statement has been utilized but it will not be displayed on the output screen. The reason for this implementation is that exit(0) has been used before the second statement. Now, save and close the file to get the output of your program.
As soon as you save the file, you have to compile and run your sample code, as quickly as you hit the “Run and Compile” option of your GCC compiler, the console will pop up on your screen which shows the predictable result.
Conclusion
This article is all about exit() function in the C programming language. We have discussed its concept and parameters in detail so that you will have a grip on the examples that we have explained in this guide. You can amend these examples of the exit() function to check its functionality in the C programming language.
using exit(1) to return from a function
linux gcc 4.4.1 C99 I am just wondering is there any advantage using the following techniques. I noticed with some code I was reading the exit number went up in value, as displayed in this code snippet.
/* This would happen in 1 function */ if(test condition 1) < /* something went wrong */ exit(1); >if(test condition 2) < /* something went wrong with another condition*/ exit(2); >
/* This would happen in 1 function */ if(test condition 1) < /* something went wrong */ return; >if(test condition 2) < /* something went wrong with another condition*/ return; >
7 Answers 7
exit() exits your entire program, and reports back the argument you pass it. This allows any programs that are running your program to figure out why it exited incorrectly. (1 could mean failure to connect to a database, 2 could mean unexpected arguments, etc).
Return only returns out of the current function you’re in, not the entire program.
return will basically return from the function and adjust the stack pointers appropriately to execute the next instructions, where as exit will cause the program itself to terminate.
using exit() in a function indicates the fatal error and program cannot recover and continue and hence, it has to be terminated.
exit will not return from a function. It will exit from the entire program
I don’t think you want to exit the entire program, right?
So just returning from the function would be fine.
/* This would happen in 1 function */ if(test condition 1) < /* something went wrong */ return; /*return type must be void in this case */ >if(test condition 2) < /* something went wrong with another condition*/ return; /*return type must be void in this case */ >
You can also explicitly specify the return type of the function and use the return value to judge whether everything went fine or not.
You’re asking us whether you should return error codes from your functions?
Well that depends upon how informative you want to be to your users. If you want to act like software usually acts and pop up a modal dialog that says
Then there’s no need for return codes.
If, however, you want to your software to be useful to your users and let them know what happened, then you better provide some kind of diagnostic information (error codes in the least). Then you can pop up a message that says:
I can’t open «foo.bar».
Does this file exist? Do you have read access to it? Is it on a network share? Maybe I should try again?