Race condition when calling function from C++


#1

I’m attempting to use ANTLR4’s C++ target from Rust. Everything is hidden behind a uint8_t function(const char * input), and I’m not explicitly using global state anywhere, yet I see all of the signs of a race condition. Segfaults, SIGABRTs, random parse errors when the input hasn’t changed, etc. Wrapping the function call in a mutex lock makes the problem go away.

Everything points to this being an issue on the ANTLR runtime’s end, but I figured I’d have someone from the Rust side take a peek as well to make sure I’m not crazy and to cover all of my bases.

My convo with the ANTLR guys thus far + link to example code: https://groups.google.com/forum/#!topic/antlr-discussion/ppulI_Z-Tf8


#2

At a glance, I don’t see any obvious sources of undefined behavior on the Rust side. There’s only one line of unsafe code (the FFI call), and its input is a *const c_char that comes from a CString (so it’s guaranteed to be null-terminated) that is valid throughout the FFI call.

The only problem I could see is if the C library stores this input pointer somewhere, and accesses it later, after the CString is dropped. I don’t think this is the case, but you could rule it out by replacing input.as_ptr() with input.into_raw(). (This will leak the string’s memory, so you should only do it for diagnostic testing, not in an actual program.)

From the antlr-discussion thread, it sounds like the C++ library is known to be non-threadsafe, so using a Mutex sounds like the correct solution.


#3

I took their “not threadsafe” comments to mean that I shouldn’t be sharing a single parser instance across threads - which I’m not. I was under the impression that multiple instances of the parser across threads shouldn’t interfere with each other. Which is maybe false?

Guess I’ll just have to keep waiting on them to reply back.