I've now got my LLVM-based model checker more or less working, but I'm seeing something a bit strange happening.
As you may remember, I started with the lli code and extended it considerably. I have retained something that looks vaguely like the original ExecutionContext stack, though I now have one stack per thread, and the whole data structure is implemented with custom collection classes that support versioning and rollback. I use a hashmap (analogous to std::map semantically) to map Value* pointers onto GenericValue objects, as per the original code. This seems to work fine nearly all of the time, but occasionally I'm seeing the memory pointed to by the Value* objects go away, and lookups fail (probably due to the same mechanism). I have noticed that during execution, Instruction* pointers have a relatively short lifetime (e.g. I can't log them and play them back later, I have to dump them to text straight away and log the text instead), so presumably whatever it is that is causing the Value/Instruction objects to move around is also at root of the interpreter's approach of mapping Value*s to GenericValues.
I suspect I'm probably right in thinking that this was probably always a bug in the interpreted (non-JITted) version of lli, and that I've inherited the problem. What is it in the interpreter that causes Value objects to move around and/or cease to exist at run time? Is there any sensible workaround short of having to do some very nontrivial changes?
Thank you in advance,
PS: Fridays seem to be a good day for showstoppers on my project for some reason!