From mboxrd@z Thu Jan 1 00:00:00 1970 From: doug.hackworth@nomos.com To: gcc-gnats@gcc.gnu.org Cc: wjtomer@nomos.com Subject: c++/3056: gcc 2.95.3 -- atexit not catching exit() call following longjmp Date: Tue, 05 Jun 2001 10:16:00 -0000 Message-id: <20010605170804.10025.qmail@sourceware.cygnus.com> X-SW-Source: 2001-06/msg00134.html List-Id: >Number: 3056 >Category: c++ >Synopsis: gcc 2.95.3 -- atexit not catching exit() call following longjmp >Confidential: no >Severity: serious >Priority: medium >Responsible: unassigned >State: open >Class: sw-bug >Submitter-Id: net >Arrival-Date: Tue Jun 05 10:16:01 PDT 2001 >Closed-Date: >Last-Modified: >Originator: Doug Hackworth >Release: gcc version 2.95.3 20010315 (release) >Organization: >Environment: i386-pc-solaris2.6 uname -a .... SunOS corvus2s 5.6 Generic_105182-19 i86pc i386 i86pc >Description: GCC does not generate an error message. The code compiles and runs, but seems to run incorrectly. All code is in the attached file, TestTerminate.cpp. There are no include files. A function (here called "Terminate()") is specified by atexit() to be executed when exit() is called. Also, setjmp() is used to specify a stack-restoration point. When exit() is called once, the function Terminate() executes. Within Terminate, atexit() is used again to re-register Terminate as the function to be executed upon exiting (it is re-registered because, since it's been called once, it has been removed from the stack); atexit returns 0, and thus appears to be working correctly. Following this, there is a longjmp() call, and this sends control back to the setjmp point in main(). When program execution resumes from this point, exit() is called a second time. However, instead of calling Terminate as it should do, the program exits. >How-To-Repeat: // ALSO IN ATTACHED FILE (from gnatsweb) extern "C" { #include #include #include #include //#include //#include //#include } jmp_buf envJmp; //================================ void Terminate(void) { fflush(stdout); printf("SETTING FOR TERMINATION\n"); int i = atexit(Terminate); printf("SETTING AFTER TERMINATION %d\n",i); longjmp(envJmp, 1); } //================================ int main(void) { atexit(Terminate); if (setjmp(envJmp) == 0) { printf("Try One\n"); exit(1); } if (setjmp(envJmp) == 0) { printf("Try Two\n"); exit(2); } printf("Exiting...\n"); exit(0); } >Fix: >Release-Note: >Audit-Trail: >Unformatted: ----gnatsweb-attachment---- Content-Type: application/octet-stream; name="TestTerminate.cpp" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="TestTerminate.cpp" Ly8jaW5jbHVkZSA8dW5pc3RkLmg+DQovLyNpbmNsdWRlIDxlcnJuby5oPg0KLy8jaW5jbHVkZSA8 c3lzL2Vycm5vLmg+DQovLyNpbmNsdWRlIDxzeXMvcGFyYW0uaD4NCi8vI2luY2x1ZGUgPHN5cy9z dGF0Lmg+DQoNCmV4dGVybiAiQyIgew0KI2luY2x1ZGUgPHN0ZGlvLmg+DQojaW5jbHVkZSA8c3Rk bGliLmg+DQojaW5jbHVkZSA8c3RyaW5nLmg+DQojaW5jbHVkZSA8c2V0am1wLmg+DQovLyNpbmNs dWRlIDxzeXMvcGFyYW0uaD4NCi8vI2luY2x1ZGUgPHN5cy90eXBlcy5oPg0KLy8jaW5jbHVkZSA8 c3lzL3N0YXQuaD4NCn0NCg0Kam1wX2J1ZiBlbnZKbXA7DQoNCi8vPT09PT09PT09PT09PT09PT09 PT09PT09PT09PT09PT0NCg0Kdm9pZCBUZXJtaW5hdGUodm9pZCkNCnsNCgkJZmZsdXNoKHN0ZG91 dCk7DQoJCXByaW50ZigiU0VUVElORyBGT1IgVEVSTUlOQVRJT05cbiIpOw0KCQlpbnQgaSA9IGF0 ZXhpdChUZXJtaW5hdGUpOyANCgkJcHJpbnRmKCJTRVRUSU5HIEFGVEVSIFRFUk1JTkFUSU9OICVk XG4iLGkpOw0KCQlsb25nam1wKGVudkptcCwgMSk7IA0KfQ0KDQovLz09PT09PT09PT09PT09PT09 PT09PT09PT09PT09PT09DQoNCmludCBtYWluKHZvaWQpDQp7DQogIGF0ZXhpdChUZXJtaW5hdGUp Ow0KDQoNCiAgaWYgKHNldGptcChlbnZKbXApID09IDApDQoJICB7DQoJCXByaW50ZigiVHJ5IE9u ZVxuIik7DQoJCWV4aXQoMSk7DQoJICB9DQoNCiAgaWYgKHNldGptcChlbnZKbXApID09IDApDQoJ ICB7DQoJCXByaW50ZigiVHJ5IFR3b1xuIik7DQoJICAgIGV4aXQoMik7DQoJICB9ICANCg0KICBw cmludGYoIkV4aXRpbmcuLi5cbiIpOw0KDQogIGV4aXQoMCk7DQp9DQo=