Panic on slice, no way to handle

Hello,
I’m new to Rust, is it true that seemingly innocuous code such:

let slice = &"Golden Eagle"[..13];

will panic causing the app to exit and there is nothing I can do to handle it. I would like to recover from it similar to handling an exception in other languages?

1 Like

Indexing operator is used when you're absolutely sure it's valid index. If you're not sure, use .get(..13) which takes same argument but returns Option instead of panicking on absence.

6 Likes

As a sidenote, I'd like to mention that Rust doesn't have a notion of exceptions - everything that is returned is a "value". There are some well-known types, such as Option or Result, which are enums that provide two variants - one for a successful value, other for a failure. Option provides no error message, just the fact that it failed, while Result provides an explicit value for the error as well (which can contain the message and other nice metadata). You need to manually match to find out what happened. With Result, you have the convenient ? operator, which lets you "pass-up" the call stack the error, if there is one while retrieveing the actual value if there is no error.
Both these enums have a bunch of useful methods defined on them. I'd encourage you to look into their docs pages to learn more about the methods - they shorten code quite a bit.

2 Likes

Is there an Option returning method to avoid divide by zero?

Yes, there is a checked_div method for each primitive integer type. Check the docs for i32 as an example.

3 Likes

How about to avoid a stack overflow panic?

You might be interested in this post:

Rust is very specific about what it considers safe vs unsafe, and there are lots of ways that a Rust program can do something you didn't want it to.

1 Like

I don't think so there is a way to even do that in theory, since the stack size limits is set by the OS dynamically, and so there is no way the program can detect it.
If you're thinking about why it works in Java, well that's because the JVM controls the Java stack depth, not the OS. So the JVM can detect it easily, since it is also running the program.

5 Likes

Stack overflow is not a panic. It is a hard abort. And I doubt you can prevent it from crashing, but it's better to indentify the points that may cause it ahead of time (long recursion) and check if they need to use the heap instead.

3 Likes

I think AOT compilation in C# does it, I assume there is code in every method to check for overflow.

You can always patch the compiler to do the same, but it will hurt performance (though probably less than in C#).

If I remember correctly, the stack overflow checking today is done with a combination of a guard page and stack probing.

The stacker crate can be useful for dynamically growing the stack. But note that recursive algorithms that use it have a noticeable performance impact compared to equivalent iterative algorithms operating on the heap.

A panic is as bad as a crash, which is unacceptable in modern software, if Rust means Robust you have left the top, the brain, off the o and got a u. C# never crashes unless you use unsafe{} which is unheard of. If one is writing distributed software such as a website one can use a safer but slower language with more hardware.

Crash is sometimes the best you can hope for, and Rust does not aim to prevent all logic bugs.

If you work in an environment a crash is unacceptable (e.g. a kernel), then there is some work mainly driven by the Rust in Linux guys to provide more panic-free functions (e.g. for collections). But I don't think stack overflow is part of those.

6 Likes

No language can protect from all resource related terminations (e.g. OOM killer), any more than an OS can protect you from a fried CPU, any more than hardware can protect you from a loss of power.

8 Likes

Actually, I am more interested to know why you would anticipate a random stack overflow? A runaway recursion is a logic bug, a not-runaway-but-still-deep recursion is something that you can reason about and replace with an iterative logic. A huge array on the stack is something that you know at compile time.
So, yeah, what do you think causes a random stack overflow?

C# never crashes unless you use unsafe{} which is unheard of; out of memory is an exception. If one is writing distributed software such as a website one can use a safer but slower language with more hardware.

A logic error causes a runaway recursion causing the stack overflow. I really like C# [especially with Visual Studio, edit and continue is most productive] as any fault, which do happen, does not bring down the app. The user just loses the last edit [GUI/web apps] or just the transaction/message being processed fails [transaction processing].

In Rust, a panic in a thread does not stop the entire process (unless the program was compiled with panic=abort). You can even catch a panic within the same thread with catch_unwind.

These are the mechanisms you would use in a Rust server to avoid unexpected problems taking down the process. (They are not considered appropriate for expected error conditions; Result is used for that. In HTTP error terms, panics are 500 and Result is everything else.)

3 Likes

Looks goodish but there is no stack trace to speed development is there, I guess one could just only use catch_unwind in release builds.