4 ms·
Is anyone else concerned about Rust’s handling of heap allocation failures? Right now the existing APIs for heap allocation are built pretty deep into the langu
by muricula 9y ago
Is anyone else concerned about Rust’s handling of heap allocation failures? Right now the existing APIs for heap allocation are built pretty deep into the language and they all panic on failure. It’s one thing for Firefox to crash when my computer completely runs out of swap, but another for Linux to panic when it’s out of heap space.
- vbezhenar 9y agoWhat's wrong with panic? Handle it, if you want. How does Linux responds when it can't allocate something from the heap?
- openasocket 9y agoTrying to catch panics in Rust is best-effort only: see https://doc.rust-lang.org/std/panic/fn.catch_unwind.html https://doc.rust-lang.org/std/panic/fn.catch_unwind.html . It's pretty strongly discouraged for general exception handling. You can check, but I have a feeling that stack unwinding requires some heap allocations, in which case an OOM panic will cause a double panic and force an abort, and thus cannot be caught. The proper solution in Rust is to use the Result type. As for what Linux does: it will invoke the "OOM Killer" which will kill user processes to clean up space.
- mcguire 9y ago"As for what Linux does: it will invoke the "OOM Killer" which will kill user processes to clean up space." Which is also pretty catastrophic. Honestly, I'm not sure which I would prefer more: a debuggable kernel panic that would be easy enough to recover from, or a still-running but possibly lobotomized machine.
- jononor 9y agoIn a decent amount of cases this will kill the offending process taking up too much memory, and then your service manager (systemd etc) will restart it. If problem was due to a memory leak etc this typically recovers the situation for a while. Of course the OOM killer might kill the wrong process, which can be annoying. This can be tweaked on a per process basis using /proc/$process/oom_score_adj or using OOMScoreAdjust in the systemd service file
- openasocket 9y agoThere are a lot of options available, some outlined here: http://www.oracle.com/technetwork/articles/servers-storage-dev/oom-killer-1911807.html http://www.oracle.com/technetwork/articles/servers-storage-d... You can configure the OOM killer to simply panic on OOM. You can also control which processes are prioritized for OOM killing, as the sibling comment mentions. Not mentioned in the article is that you can set per-process memory usage limits, where subsequent calls to malloc() will return NULL if trying to allocate more. Some applications will try to properly handle that condition, many will just segfault or do some kind of controlled abort. For a lot of applications failing is the right behavior on memory allocation failure. I mean, presumably you weren't trying to allocate that memory on a whim, you need that memory to function properly! So there really isn't any sane way to continue functioning without either disabling functionality or hanging until memory becomes available. Either way, I generally prefer something to unambiguously fail so I can restart it than have a "gray failure" where the system tries to keep limping along.
- dbaupp 9y agoAs the sibling says, catching panics isn't as reliable as Result for error handling, and, anyway, the parent was slightly wrong: the standard library types like Box and Vec abort on allocation failure, not panic.
- frazar0 9y agoYes. The issue is actually being worked on. For example, the draft RFC for fallible collection allocations is now in final comment period [0]. Edit: fix link [0] https://github.com/rust-lang/rfcs/pull/2116 https://github.com/rust-lang/rfcs/pull/2116
- dbaupp 9y agoThe allocation most built in to the language is https://doc.rust-lang.org/std/heap/trait.Alloc.html https://doc.rust-lang.org/std/heap/trait.Alloc.html and that returns a Result. Some std APIs like Box and Vec do just panic/abort on allocation failure (although that's changing), but these are all library types defined in std, neither the language itself nor the lower level core library (more relevant to embedded platforms) do any allocation.
- muricula 9y agoUnless I'm mistaken, the little-b `box` keyword panics on failure. Isn't that required to construct a type in place in heap memory?
- steveklabnik 9y agoThe box keyword isn't in stable Rust yet, and isn't even "the box keyword" anymore. https://github.com/rust-lang/rfcs/blob/master/text/1228-placement-left-arrow.md https://github.com/rust-lang/rfcs/blob/master/text/1228-plac... is the latest RFC I believe, but even that I believe is changing since the latest allocator API work, though I'm not 100% sure.
- dbaupp 9y agoMy understanding is that the latest RFCes touching that syntax (not sure if they're implemented) have it overloaded with traits, and I would guess/hope that it's possible to implement those traits in a way that is fallible (e.g. hypothetically 'impl BoxSyntax for Result<Box<T>, AllocationError>').
- gcp 9y agothey all panic on failure. It’s one thing for Firefox to crash when my computer completely runs out of swap Actually most large allocations in Firefox are fallible and the browser will only crash when it can't deal with an allocation in security-sensitive code. So that's a terrible example!