Skip to content

Add option --stack-trace to print the stack trace of a failure #3681

@celinval

Description

@celinval

Requested feature: Enable Kani to print stack traces when a failure occur
Use case: Debugging failures can be very painful, especially for things that cannot be easily reproduced with concrete playback or very generic errors such as unwrap() on None value. Providing a stack trace of a failure can really help narrow down the exact location of a failure.

Test case: Debugging the following harness from this PR:

    #[kani::proof_for_contract(copy_nonoverlapping)]
    fn check_copy_nonoverlapping() {
        run_with_arbitrary_ptrs::<char>(|src, dst| unsafe {
            copy_nonoverlapping(src, dst, kani::any())
        });
    }

    fn run_with_arbitrary_ptrs<T: Arbitrary>(harness: impl Fn(*mut T, *mut T)) {
        let mut generator1 = PointerGenerator::<100>::new();
        let mut generator2 = PointerGenerator::<100>::new();
        let ArbitraryPointer {
            ptr: src,
            status: src_status,
            ..
        } = generator1.any_alloc_status::<T>();
        let ArbitraryPointer {
            ptr: dst,
            status: dst_status,
            ..
        } = if kani::any() {
            generator1.any_alloc_status::<T>()
        } else {
            generator2.any_alloc_status::<T>()
        };
        kani::assume(supported_status(src_status));
        kani::assume(supported_status(dst_status));
        harness(src, dst);
    }

I was getting the following failure:

Checking harness intrinsics::verify::check_copy_nonoverlapping...

VERIFICATION RESULT:
 ** 1 of 856 failed (3 unreachable)
Failed Checks: Only a single top-level call to function _RNCNCINvNtCsf4mLL5B4Lhf_4core10intrinsics19copy_nonoverlappinghEs0_0s_0B8_ when checking contract _RNCNCINvNtCsf4mLL5B4Lhf_4core10intrinsics19copy_nonoverlappinghEs0_0s_0B8_
2024-11-02T01:43:52.2508870Z  File: "/Users/runner/work/verify-rust-std/verify-rust-std/head/library/core/src/intrinsics.rs", line 3311, in _RNCNCINvNtCsf4mLL5B4Lhf_4core10intrinsics19copy_nonoverlappinghEs0_0s_0B8_

VERIFICATION:- FAILED

This is pointing to the #[modifies] clause in the contract, which is the following:

#[cfg_attr(kani, kani::modifies(crate::ptr::slice_from_raw_parts(dst, count)))]

Concrete playback wouldn't help me in this one since the modifies clause is an artifact of contract checking. The failure is also very CBMC instrumentation specific, which doesn't help at all. I tried the trace / visualize, but I got a trace with over 3000 steps. 😞

The best way I found to narrow this down was to use the --stack-trace option from CBMC, however, the trace is all mangled and hard to parse. It would be fantastic if Kani could provide a more user friendly trace here.

Metadata

Metadata

Assignees

No one assigned

    Labels

    [C] Feature / EnhancementA new feature request or enhancement to an existing feature.[E] User ExperienceAn UX enhancement for an existing feature. Including deprecation of an existing one.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions