Defer lexical bug of my own making

I was running down a crash today and traced it to the moral equivalent of:

pub fn global_deinit(ga: *GA) void {
    ga.mx.lock();
    defer ga.mx.unlock();

    // ... lots of intervening code setting things to invalid so use-after-free gets caught


    // Finally, we can clear the lock
    ga.mx = undefined;  // Whoops.  This blasts the lock before defer can run
}

Is there anything that I could have done to have caught this at compile?

Solution is:

pub fn global_deinit(ga: *GA) void {
    ga.mx.lock();
    defer {
        ga.mx.unlock();
        ga.mx = undefined;
    }

    // ... code 
}

related:

Maybe a check similar to what is shown in the video / implemented by clr could catch this statically. (but clr is a research experiment)
You also could check whether valgrind catches this on linux.

Maybe in the future Zig will have some kind of safety check or error?
Not sure whether it would be at compile time or runtime.

1 Like