Panic handler in no_std for Aurix µC

Hello,

I am new to this rust language for embedded targets and I was trying out ways it can panic and return the information back to the file the function is called from (in my case it is .c file).

What I am trying to achieve is, if you try to access an element in an array that doesn't exist, usually rust will panic and give error. But, if the index is being passed at runtime, then rust will compile the code, but will enter into panic and stay forever, when you flash the software.

Is there a way to know, why it panicked or some error information that can be provided back to C and then may be reset the target?

below is the rust code that I am trying to work with panics

#[no_mangle]
pub extern "C" fn rust_fn(idx: *const u8) -> u8
{
    let mut data: [u8; 32] = [0; 32];

    data[0] = 42; // hex val - 2A

    data[7] = 26; // hex val - 1A

    if idx.is_null()
    {
        return E_PARAM;
    }

    let idx_deref: usize = unsafe { *idx as usize };

      unsafe 
      {
          core::ptr::write_volatile(&mut data[idx_deref], 64); // hex val - 40
      }

    return E_OK;
}

#[no_mangle]
pub extern "C" fn get_runtime_idx() -> usize
{
    let mut n: usize = 0;

    for i in 0..5
    {
        n += i;
    }

    return n+50; // value of n is 10
}

#[panic_handler]
fn panic(_info: &PanicInfo) -> !
{
    LAST_ERROR.store(E_PANIC_OOB, Ordering::Relaxed);

    loop {} // infinite loop to halt execution on panic
}

Below is the C code where these 2 functions are being called:

    uint8 idx = get_runtime_idx();

    volatile int ret_code = rust_fn(&idx);

Since the code goes into panic and never returns, I cannot read the ret_code or any error to know the cause.

Any ideas or help into the topic will be really helpful and is greatly appreciated.

Thanks

if you want to handle the error, you should not use the array/slice index operator, but instead use fallible APIs, e.g. slice.get().

// the array of data
let data = [0u8; 32];

// out-of-bound indexing will panic:
let x = data[100];

// `get()` will return `None` for out-of-bound access:
if let Some(y) = data.get(100) {
}

Yes, there are way to handle the error in Rust like get() or do some checks to prevent it. But, what I need is, if it goes into panic, what are the ways to know the cause in embedded target, when it stays in loop{}.

The PanicInfo argument the panic handler receives can be used to format the panic message. You could format the panic message and then call a function you define in C to tell it what caused the panic. If you want control flow to return from rust_fn, you will have to implement full unwinding however. That and resetting the entire microcontroller are the only non-UB way to escape from the panic handler. Also note that panicking should only be used for programming bugs. It should not be used for regular error handling like you would use return codes in C or Result in Rust for.

1 Like

you want the error be returned to the caller, it's your responsibility to design an API that does so.

panic is not an error handling feature, it is instead to catch bugs in code. it is simply not the right tool for your use case.

technically, you can catch a (unwinding) panic and turn it into a Err, but again, this is mostly a safety feature, it is NOT an error handling mechanism. see: