LLDB woes - what expressions can you evaluate?

Calling evaluate in lldb-rust is a bit of a crapshoot, sometimes it works sometimes it just fails at the most basic things.

For example:

If do the following

(lldb) evaluate t1()
(lldb) evaluate t2()
(lldb) evaluate t3()
(lldb) evaluate t4()

Some will fail.

use chrono::Utc;

pub struct T {
    a: usize
}

impl T {
    pub fn new() -> T {
        T {
            a: 1
        }
    }
}


// This works
fn t1() -> T {
    T::new()
}

// This works
fn t2() -> std::time::Duration {
    std::time::Duration::new(1, 0)
}

// This does not work
fn t3() -> chrono::DateTime<chrono::Utc> {
    chrono::Utc::now()
}

// This works
fn t4() -> i64 {
    chrono::Utc::now().timestamp()
}

// This works
fn t5() -> ordered_float::NotNan<f64> {
    ordered_float::NotNan::new(4.0).unwrap()
}


// This does not work
fn t6() -> rust_decimal::Decimal {
    rust_decimal::Decimal::MAX
}


const D: &'static rust_decimal::Decimal = &rust_decimal::Decimal::MAX;

// This works
fn t7() -> &'static rust_decimal::Decimal {
    D
}

It's not really clear why they're failing. I don't understand what the difference is between that values that I'm trying to evaluate. It's all very strange and inconsistent.

I expect it has to do with ABI (calling convention). All of the types which work have a "scalar" or "scalar pair" ABI, whereas the types which don't have an "aggregate" ABI, which means it gets lowered using effectively an out pointer.

lldb can be taught how to handle this, but apparently hasn't been yet. Unfortunately, while I'm fairly sure this is the underlying cause, I have no idea how lldb handles different return passing ABIs in C/C++.

4 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.