Internal Error -3 While Unwinding Stack
Contents |
the discussions that are taking place. One of the more interesting discussions (or should I say flamewars) evolve around the concept of stack unwinding in Rust. I consider myself very strongly on one side of this topic but I have not been rust catch panic aware of how hot this topic is until I accidentally tweeted by preference. Since then rust backtrace line numbers I spent a bit of time reading up no the issue and figured I might write about it since it is quite an rust panic interesting topic and has huge implications on how the language works. What is this About? As I wrote last time, there are two different error handling models in Rust these days. In this blog post I will call rust exceptions them result carriers and panics. A result carrier is a type that can carry either a success value or a failure value. In Rust there are currently two very strong ones and a weak one: the strong ones are Result
Rust Error Handling
weak one which is bool which generally indicates success by signalling true and failure by signalling false. There is a proposal to actually formalize the carrier concept by introducing a Carrier trait that can (within reason) convert between any of those types which would aid composability. The second way to indicate failure is a panic. Unlike value carriers which are passed through the stack explicitly in the form of return values, panics fly through the stack until they arrive at the frame of the task in which case they will terminate it. Panics are for all intents and purposes task failures. The way this works is by unwinding the stack slice by slice, invoking cleanup code at each level and finally terminate the task. Panics are intended for situations where the runtime runs out of choices about how to deal with this failure. Why the Panic? Currently there is definitely a case where there are too many calls in Rust that will just panic. For me one of the prime examples of something that panics in a not very nice way is the default print function. In fact, your rust Hello World example can panic if invoked the wrong way: $ ./hello Hello World! $ ./hello 1< /dev/null task '
our program. It assumes that memory allocation never fails. This assumption is blatantly false. Granted, in a virtual-memory system allocation limits are rather high. In fact, the computer is not even limited by the
Rust Try
size of its physical memory. The only way memory allocation may fail is if you rust result run out of space in the swap file on your disk. Now, that's not something unheard of in the world of rust unwrap huge applications and multimedia files. An industrial-strength program should protect itself from it. The question is, how? What should a program do when the call to new fails? First of all, if we don't do anything http://lucumr.pocoo.org/2014/10/30/dont-panic/ about it (as indeed we didn't), the system will terminate us with extreme prejudice. That's totally unacceptable! The next, slightly more acceptable thing would be to print a good-bye message and exit. For a program such as our calculator that might actually be the correct thing. It's not like the user runs the risk of losing hours of work when the calculator unexpectedly exits. There are a few different ways to https://www.relisoft.com/book/tech/5resource.html globally intercept a memory failure. One is to catch the bad_alloc exception--more about it in a moment--another, to create your own "new handler" and register it with the runtime at the beginning of your program. The function set_new_handler is defined in the header
Status Importance Assigned to Milestone SBCL Edit New Undecided Unassigned Edit You need to log in to change this bug's https://bugs.launchpad.net/bugs/999972 status. Affecting: SBCL Filed here by: Alastair Bridgewater When: 2012-05-15 Target Distribution Baltix BOSS Juju Charms Collection Elbuntu Guadalinex Guadalinex Edu Kiwi Linux nUbuntu PLD Linux Tilix tuXlab Ubuntu Ubuntu Linaro Evaluation Build Ubuntu RTM Package (Find…) Project (Find…) Status Importance New Undecided Assigned to Nobody Me Comment on this change (optional) Email me about changes to internal error this bug report Also affects project (?) Also affects distribution/package Nominate for series Bug Description Found this one on a lightly-loaded test server. If the SBCL runtime is compiled with gcc-4.3 (but not with gcc-4.4), and a GC occurs while doing a backtrace when there's an internal-error trap context on the stack, the system fails a GC internal error -3 assertion at the bottom of scavenge(). Found on 1.0.50.1 (x86), confirmed on 1.0.23 (x86-64), 1.0.35 (x86), and 1.0.56.51 (x86). Again, this only happens when compiling with gcc-4.3, and I have only tested on x86 and x86-64 linux boxes. My primary questions are: Why does this happen? Why doesn't it happen with gcc-4.4? And, finally, how do we know that nothing similar (or worse) happens in such scenarios, regardless of which compiler is used? nyef@kana:~/src/lisp/sbcl$ echo "*features* (load (compile-file \"backtrace-test.lisp\")) (dotimes (i 5000) (try-to-break))" | sh ./sbcl-git/run-sbcl.sh (running SBCL from: /home/nyef/src/lisp/sbcl/sbcl-git) This is SBCL 1.0.56.51-1a104ef, an implementation of ANSI Common Lisp. More information about SBCL is available at