DBD::SQLite alignment fix

jhorwitz on 2004-10-05T00:20:18

I have a patch that fixes DBD::SQLite on Sparc so it passes all its tests and doesn't core dump. Turns out GCC likes to inline its own "optimized" version of memcpy, which assumes 8-byte aligned structures. SQLite does a buttload of casting from char * to structures and back, which wreaks havoc on this assumption.

The solution was to coerce GCC into not using its own inline memcpy without affecting other inlining. Turns out all you have to do is make the size argument a variable rather than a constant. So I changed lines like this: memcpy(to, from, 8); to this: int sz = 8; memcpy(to, from, sz);

I'll send this off to Matt tonight, and I should also port it to the main SQLite codebase. This took way too long to figure out...


gcc buggy?

nicholas on 2004-10-16T22:26:42

Given that memcpy is prototyped void *memcpy(void *dst, const void *src, size_t len); is sqlite actually at fault here? Or is the gcc optimisation buggy? I'm not a sufficiently good C standards guru to know this, even if I looked at precisely what the code is doing. (Which I confess, I haven't)

Re:gcc buggy?

jhorwitz on 2004-10-16T22:44:37

I believe both are at fault. GCC should not provide this optimization in *all* cases, at least without providing an option on those platforms to specifically disable it (curiously, there's an option for MIPS but not Solaris).

On the SQLite side, arrays of char * were being casted to structs and then memcpy'd. With this layout, every other array element was misaligned on Solaris, but it was fine on x86. Very, very bad. D. Richard Hipp (author of SQLite) and I actually worked out a better solution than my patch -- using the fact that malloc() always returns 8-byte aligned addresses on Solaris, he fiddled with the allocation of the structures to guarantee 8-byte alignment. Much cleaner! I believe version 3.0.8 has this fix.