4 ms·
I have bad news for you: If the project works perfectly on an older C compiler, but crashes hard on a more recent one, then that means the code has undefined be
by munch117 5y ago
I have bad news for you: If the project works perfectly on an older C compiler, but crashes hard on a more recent one, then that means the code has undefined behaviour.
Probably it's doing some type-punning - using casts or unions to access the same memory as multiple different types. This is a pretty normal thing to in an interpreter, sometimes you will bend the rules for performance reasons, and get away with it, too. As least you used to get away with it in the old days. But as modern compilers get better at exploiting the rules of undefined behaviour to improve performance in correct programs, some of the things you would get away with before no longer work.
Undefined behaviour can be superficial and easy to fix, but I'm afraid that in this type of project it can be deeply rooted in the data structures.
And that is what makes me a bit pessimistic on your behalf, esp. as you say you're not a C programmer. Because you need a solid understanding of the C memory model and undefined behaviour rules to deal with something like this. Although, after taking a quick look at the source, I have to say that it does look well-structured and pretty thoroughly commented, so maybe there is a chance.
What I would look for is unions and void pointers, where the program writes using one type and reads using a different type. That ".v.p" thing looks like a good candidate for where to look: Is a "value" union field always read from the same field that was last written? Is the value.p void* always cast to the correct type that was assigned to it?
- eslaught 5y agoSome of this you may be able to hack around via disabling compiler optimizations. For example, -fno-strict-aliasing will disable optimizations that rely on assuming objects of different types will never alias (an assumption that gets violated by type punning). For that matter, if you're not starting on -O0, you probably should. Don't enable optimizations until it's working correctly. Of course, if the issue is that the sizes of types changed (e.g. 32 to 64 bit), no amount of flags will fix that automatically for you. Though you could still install a 32 bit compiler on a modern distro.
- sargstuff 5y agouse gcc -fdump-translation-unit switch compile old code, compile new code. compare the differenct between the old gcc AST against the new gcc AST (or differences between the AST's generated when different compile switches are used) Doesn't mean there aren't assembly language differences, but will narrow things down.