From octave-maintainers-request at bevo dot che dot wisc dot edu Tue Nov 5 11:59:49 2002 Subject: signal handling From: "John W. Eaton" To: octave-maintainers mailing list Date: Tue, 5 Nov 2002 11:59:41 -0600 --U4xrTDX5e4 Content-Type: text/plain; charset=us-ascii Content-Description: message body text Content-Transfer-Encoding: 7bit I'm thinking about how to improve Octave's signal handling and error recovery. Currently, when Octave receives an interrupt signal, it simply tries to use longjump to get back to the beginning of the main interpreter loop. This approach has at least two major problems. First, there is no guarantee that a longjump out of a signal handler will even work. Second, it skips over the destructors for all the objects that have been created up to the point of the signal, which leads to big memory leaks. The program below provides an outline of how signal handling in Octave currently works and also how I propose to improve it. If you compile without -DUSE_EXCEPTIONS, you will get the current behavior. Run it and type Control-C a few times just after the "sleeping" message appears (so you are sure to have some memory allocated by an intermediate object) and watch the process grow (with top, ps, whatever). It should grow in increments of about 8MB and you should see more messages from the big_memory_hog constructor than from the destructor. My proposal is to modify the signal handler so that it simply sets a global variable and returns. Then when Octave hits a QUIT macro, it will throw a C++ exception which will be caught at the top level. If we then make sure that all resources are managed properly in object constructors/destructors, the exception handling code should take care of deleting any temporary objects. I think that in most instances, this is already true, so most of that work is done. What remains is to add calls to QUIT in a number of places in the Octave sources. To see how this method works, compile the example below with -DUSE_EXCEPTIONS and try the same experiment as above. This time, you should see the same number of messages from the big_memory_hog constructor and destructor so the process should not grow (the total size should never be too much more than 8MB). This method will take care of exceptions that happen in the C++ code that Octave uses. For the Fortran bits and other library code that we call, I think we will need a slightly different approach. But we only have to worry about code that may run for a significant amount of time (otherwise, we just wait for it to finish, and the exception handling stuff will take care of getting us back to the top level without too much delay). My proposal for Fortran or other long-running foreign code is to set up a separate signal handling/longjump scheme around them. The idea is that when an interrupt signal is received, we will jump out of the signal handler, but only back to the point where the foreign code was called. Then we throw an exception and make our way back to the top level, using the exception handler code to clean up as we go. This does not solve the problem of resource management for the foriegn code or on systems where jumping out of a signal handler does not work (I don't know what to do about that, other than ignore interrupts on those systems). It is OK for the Fortran code that Octave uses because that stuff doesn't do any memory allocations and typically does not open external files. But for other foriegn code, we may leak memory or other resources. The only solution I can see for that is to make sure that the foreign code manages its resources properly in the presence of interrupt signals. Comments? Thanks, jwe --U4xrTDX5e4 Content-Type: application/octet-stream Content-Disposition: attachment; filename="except.cc" Content-Transfer-Encoding: base64 I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8c3lzL3R5cGVzLmg+CiNpbmNsdWRlIDx1bmlz dGQuaD4KI2luY2x1ZGUgPHNpZ25hbC5oPgojaW5jbHVkZSA8Y3N0ZGxpYj4KI2luY2x1ZGUgPGNt YXRoPgoKI2lmZGVmIFVTRV9FWENFUFRJT05TCgpib29sIGludGVycnVwdF9zdGF0ZSA9IGZhbHNl OwoKI2RlZmluZSBRVUlUIFwKICBkbyBcCiAgICB7IFwKICAgICAgaWYgKGludGVycnVwdF9zdGF0 ZSkgXAogICAgICAgIHsgXAogICAgICAgICAgaW50ZXJydXB0X3N0YXRlID0gZmFsc2U7IFwKICAg ICAgICAgIHN0ZDo6Y2VyciA8PCAiZG9fc29tZXRoaW5nOiB0aHJvd2luZyBpbnRlcnJ1cHRfZXhj ZXB0aW9uIiBcCiAgICAgICAgICAgICAgICAgICAgPDwgc3RkOjplbmRsOyBcCiAgICAgICAgICB0 aHJvdyBpbnRlcnJ1cHRfZXhjZXB0aW9uICgpOyBcCiAgICAgICAgfSBcCiAgICB9IFwKICB3aGls ZSAoMCkKCiNkZWZpbmUgSlVNUF9UT19UT1BfTEVWRUwgZG8geyBpbnRlcnJ1cHRfc3RhdGUgPSB0 cnVlOyB9IHdoaWxlICgwKQoKI2RlZmluZSBJTklUX0pNUF9CVUYgZG8geyB9IHdoaWxlICgwKQoK I2Vsc2UKCiNpbmNsdWRlIDxzZXRqbXAuaD4KCnNpZ3NldF90IHNpZ25hbF9tYXNrOwoKam1wX2J1 ZiB0b3BfbGV2ZWw7CgojZGVmaW5lIFFVSVQgZG8geyB9IHdoaWxlICgwKQoKI2RlZmluZSBKVU1Q X1RPX1RPUF9MRVZFTCBsb25nam1wICh0b3BfbGV2ZWwsIDEpCgojZGVmaW5lIElOSVRfSk1QX0JV RiBcCiAgZG8gXAogICAgeyBcCiAgICAgIHNhdmVfc2lnbmFsX21hc2sgKCk7IFwKICAgICAgaWYg KHNldGptcCAodG9wX2xldmVsKSAhPSAwKSBcCiAgICAgICAgeyBcCiAgICAgICAgICBzdGQ6OmNv dXQgPDwgIlxuIjsgXAogICAgICAgICAgcmVzdG9yZV9zaWduYWxfbWFzayAoKTsgXAogICAgICAg fSBcCiAgICB9IFwKICB3aGlsZSAoMCkKCnZvaWQKc2F2ZV9zaWduYWxfbWFzayAodm9pZCkKewog IHN0ZDo6Y2VyciA8PCAic2F2aW5nIHNpZ25hbCBtYXNrIiA8PCBzdGQ6OmVuZGw7CiAgc2lncHJv Y21hc2sgKDAsIDAsICZzaWduYWxfbWFzayk7Cn0KCnZvaWQKcmVzdG9yZV9zaWduYWxfbWFzayAo dm9pZCkKewogIHN0ZDo6Y2VyciA8PCAicmVzdG9yaW5nIHNpZ25hbCBtYXNrIiA8PCBzdGQ6OmVu ZGw7CiAgc2lncHJvY21hc2sgKFNJR19TRVRNQVNLLCAmc2lnbmFsX21hc2ssIDApOwp9CgojZW5k aWYKCiNkZWZpbmUgUkVUU0lHVFlQRSB2b2lkCgp0eXBlZGVmIFJFVFNJR1RZUEUgc2lnX2hhbmRs ZXIgKGludCk7CgpzaWdfaGFuZGxlciAqCnNldF9zaWduYWxfaGFuZGxlciAoaW50IHNpZywgc2ln X2hhbmRsZXIgKmhhbmRsZXIpCnsKICBzdHJ1Y3Qgc2lnYWN0aW9uIGFjdCwgb2FjdDsKICBhY3Qu c2FfaGFuZGxlciA9IGhhbmRsZXI7CiAgYWN0LnNhX2ZsYWdzID0gMDsKICBzaWdlbXB0eXNldCAo JmFjdC5zYV9tYXNrKTsKICBzaWdlbXB0eXNldCAoJm9hY3Quc2FfbWFzayk7CiAgc2lnYWN0aW9u IChzaWcsICZhY3QsICZvYWN0KTsKICByZXR1cm4gb2FjdC5zYV9oYW5kbGVyOwp9Cgp2b2lkCnNp Z2ludF9oYW5kbGVyIChpbnQpCnsKICBzdGQ6OmNlcnIgPDwgInNpZ2ludF9oYW5kbGVyIiA8PCBz dGQ6OmVuZGw7CiAgSlVNUF9UT19UT1BfTEVWRUw7Cn0KCmNsYXNzCmludGVycnVwdF9leGNlcHRp b24KewogIC8vIEVtcHR5Lgp9OwoKY2xhc3MKYmlnX3N0b3JhZ2VfaG9nCnsKcHVibGljOgoKICBi aWdfc3RvcmFnZV9ob2cgKGludCBuID0gMTAyNCoxMDI0KSA6IHAgKDApCiAgewogICAgc3RkOjpj ZXJyIDw8ICJiaWdfc3RvcmFnZV9ob2c6IGNvbnN0cnVjdG9yIiA8PCBzdGQ6OmVuZGw7CiAgICBp bml0IChuKTsKICB9CgogIH5iaWdfc3RvcmFnZV9ob2cgKHZvaWQpCiAgewogICAgc3RkOjpjZXJy IDw8ICJiaWdfc3RvcmFnZV9ob2c6IGRlc3RydWN0b3IiIDw8IHN0ZDo6ZW5kbDsKICAgIGRlbGV0 ZSBbXSBwOwogIH0KCiAgdm9pZCBpbml0IChpbnQgbikKICB7CiAgICBwID0gbmV3IGRvdWJsZSBb bl07CiAgICBmb3IgKGludCBpID0gMDsgaSA8IG47IGkrKykKICAgICAgcFtpXSA9IHNpbiAoaSkg KiBjb3MgKGkpOwogIH0KCnByaXZhdGU6CgogIGRvdWJsZSAqcDsKfTsKCnZvaWQKZG9fc29tZXRo aW5nICh2b2lkKQp7CiAgc3RkOjpjZXJyIDw8ICJkb19zb21ldGhpbmc6IGNyZWF0aW5nIGJpZ19z dG9yYWdlX2hvZyBvYmplY3QiIDw8IHN0ZDo6ZW5kbDsKCiAgYmlnX3N0b3JhZ2VfaG9nIHg7Cgog IHN0ZDo6Y2VyciA8PCAiZG9fc29tZXRoaW5nOiBzbGVlcGluZyBmb3IgdGhyZWUgc2Vjb25kcyIg PDwgc3RkOjplbmRsOwoKICBzbGVlcCAoMyk7CgogIFFVSVQ7CgogIHN0ZDo6Y2VyciA8PCAiZG9f c29tZXRoaW5nOiByZXR1cm5pbmciIDw8IHN0ZDo6ZW5kbDsKfQoKaW50Cm1haW4gKHZvaWQpCnsK ICBpbnQgayA9IDA7CgogIElOSVRfSk1QX0JVRjsKCiAgc3RkOjpjZXJyIDw8ICJtYWluOiBzZXR0 aW5nIFNJR0lOVCBoYW5kbGVyIiA8PCBzdGQ6OmVuZGw7CgogIHNldF9zaWduYWxfaGFuZGxlciAo U0lHSU5ULCBzaWdpbnRfaGFuZGxlcik7CgogIHN0ZDo6Y2VyciA8PCAibWFpbjogZW50ZXJpbmcg bWFpbiBsb29wIiA8PCBzdGQ6OmVuZGw7CgogIHdoaWxlICgxKQogICAgewogICAgICB0cnkKICAg ICAgICB7CiAgICAgICAgICBzdGQ6OmNlcnIgPDwgIm1haW46IGNhbGxpbmcgZG9fc29tZXRoaW5n IiA8PCBzdGQ6OmVuZGw7CgogICAgICAgICAgZG9fc29tZXRoaW5nICgpOwogICAgICAgIH0KICAg ICAgY2F0Y2ggKGludGVycnVwdF9leGNlcHRpb24pCiAgICAgICAgewogICAgICAgICAgc3RkOjpj ZXJyIDw8ICJpbnRlcnJ1cHRfZXhjZXB0aW9uIGNhdWdodCIgPDwgc3RkOjplbmRsOwogICAgICAg IH0KCiAgICAgIHN0ZDo6Y2VyciA8PCAiayA9ICIgPDwgayA8PCBzdGQ6OmVuZGw7CgogICAgICBp ZiAoaysrID4gMjApCglicmVhazsKICAgIH0KfQo= --U4xrTDX5e4--