6 ms·
This quote is interesting: “ I’m a bit vague on the details here because it’s not my expertise, but Rust itself can’t even properly clean up its memory and just
by bluejekyll 6y ago
This quote is interesting: “ I’m a bit vague on the details here because it’s not my expertise, but Rust itself can’t even properly clean up its memory and just returns error when it hits such a condition. Clearly something to fix before a libcurl with hyper could claim identical behavior and never to leak memory”.
So Rust aborts on invalid memory accesses, unwrap on None, etc. It does not abort on memory leaks. I don’t see Rust aborting in that context as much different from a segfault, and it guards against more situations than a segfault is able to do. Additionally, when stack unwinding is enabled (default) aborts can be caught during runtime and handled specially, if that’s necessary.
Edit: I said “aborts” above, I should have said “panics”. The option in Rust is to disable unwinding and instead abort immediately: https://doc.rust-lang.org/edition-guide/rust-2018/error-handling-and-panics/aborting-on-panic.html https://doc.rust-lang.org/edition-guide/rust-2018/error-hand...
That can’t be caught at runtime, to be clear.
- dochtman 6y agoMore details here: https://github.com/hyperium/hyper/issues/2265#issuecomment-693020519 https://github.com/hyperium/hyper/issues/2265#issuecomment-6...
- steveklabnik 6y ago> So Rust aborts on invalid memory accesses, unwrap on None, etc. Rust will panic on these things, and panics can abort, or unwind. Unwind is the default. That's not what's being talked about here, I don't think. This is about alloc::alloc::handle_alloc_error, which was not allowed to unwind at the time the linked comment was made. But in the last few hours, https://github.com/rust-lang/rust/pull/76448 https://github.com/rust-lang/rust/pull/76448 was linked to, which shows how that has since changed.
- brundolf 6y agoThis is an interesting case for error-handling, because a) it can happen virtually anywhere, so handling it with Result would add huge API overhead in terms of ergonomics (given that most code never really has to think about it), yet b) it's very important that it is able to be handled in certain kinds of system contexts, which panics are not designed to facilitate. Most error cases seem to fall neatly into one camp or the other (something you always want to explicitly handle, or something where you just want to abort), but this one doesn't. handle_alloc_error seems to do well enough as a workaround, but (from my superficial reading of the GitHub thread) it feels like just a very specific "poor-man's try/catch" for this one particular case. It feels like a workaround. In general I'm a big fan of Result/panic in place of traditional exceptions, but this usecase makes it really quite unideal
- a1369209993 6y ago> This is an interesting case for error-handling, [...] Part of the problem is that it's actually two different error cases: A, the data we're operating on is too large, versus B: the system as a whole doesn't have enough memory. Case A is obviously[0] a explicitly-handle error (just like "the data we're operating on is malformed"), whereas case B is obviously a just-give-up error (like "the system doesn't have a floating-point unit"). But there doesn't seem to be any practical way to reliably distinguish the two cases, and it's not clear they can be rigorously separated even in principle. 0: we might decide to 'handle' it by aborting, but that's not special to allocation
- steveklabnik 6y ago> This is an interesting case for error-handling, because I think this is a very good articulation of this space, thank you. > It feels like a workaround. I agree, but the needed work to improve this has taken a very, very, very long time, and so I think workarounds are ultimately helpful. We'll get there...
- brundolf 6y agoI think it can honestly be traced down to just how wide a stretch of usecases Rust itself has managed to span. For systems, this arguably is "something you always want to explicitly handle", whereas for applications it's almost always "something where you just want to abort". The level of abstraction is very different, but a single language is spanning both. Or, more precisely, a single standard library. Just spitballing: maybe one solution could be an alternate set of standard primitives, specifically for low-level work, that do return a Result for everything that might trigger OOM? Maybe those could be abstracted out of the current standard library, and the existing ("application-level") APIs could wrap them with a panic?
- pixel_fcker 6y agoThis is AFAICT essentially what wg-allocators is working on where you can directly specify an allocator in collections (and alloc() returns a Result): https://github.com/TimDiekmann/alloc-wg https://github.com/TimDiekmann/alloc-wg From the readme it sounds like this has actually started to be upstreamed now?
- quotemstr 6y agoI'm still annoyed that the Rust people screwed up error handling so badly. The designers should have gone with classical exceptions like other languages, but instead went for a fashionable-at-the-time combination of error codes and added exceptions (spelled "panics"), cribbed for some reason from Go. And on top of that, the Rust designers copied one of the most annoying parts of the C++ ecosystem: a compiler switch for changing exception behavior. The overall result is that everyone pays the cognitive cost of exception (spelled "unwind" in Rust) safety, pays the syntactic and runtime costs of error code checking, pays the runtime cost of unwind tables, and still can't actually rely on unwinding to actually work, because anyone can just turn panics into aborts. I hope for a language with Rust's focus on memory safety but without Rust's weird fashionable-in-the-2010s language design warts.
- pcwalton 6y agoIf Rust had gone with exceptions, we'd have lost the entire embedded community. You have to realize that -C panic=abort was added in no small part because of a hostile fork of the language that removed the unwinding mechanism. I happen to like exceptions in principle, but for a lot of low-level embedded code they're a deal breaker.
- steveklabnik 6y ago> The overall result is that everyone pays the cognitive cost of exception (spelled "unwind" in Rust) safety Very, very few people have to think about unwind safety, because it really only comes into play when you're writing unsafe code, and relying on the ability for panics to be caught. Many folks aren't writing any unsafe, and many who are are doing it explicitly in a panic=abort environment. And most don't rely on panics being able to be caught in the first place. So, some subset of library authors have to pay attention to unwind safety in some cases. This is hardly "everyone." > pays the syntactic It's one character. > and runtime costs of error code checking, Exceptions also have runtime costs. I'm not aware of anything demonstrating that there is a really major difference between the two in real systems. I would be interested in reading more about this! Most of the discussion I've seen focuses on microbenchmarks, which can be very different than real code. > pays the runtime cost of unwind tables, Only if you want them, as you yourself mention, you can turn this off. And many do.