So I spent the evening getting Smiles working in 64bit Linux (Ubuntu 10.10) as well as the Mac. Here are the results:

Smiles HD, 64bit binary running on 'The Zotac' -- Ubuntu 10.10 Desktop

And the Mac again:

Smiles HD on the Mac again, this time in 64 bits

And a closeup of the processes section:

A zoom of the process, showing 64bit mode. The CPU usage is due to it being a debug build.

Getting it working on the Mac wasn’t really necessary, but I really like Xcode’s debugging tools. They made tracing the issue very straightforward. I had two VNC windows going almost constantly, as I’d make changes on the Workstation PC, commit to SVN, and sync on both the Mac and the Zotac.

I had a pretty good idea what was the cause of my crashes, but I still hunted for some resources.

MSDN 32-bit to 64bit: http://msdn.microsoft.com/en-us/library/3b2e7499%28VS.71%29.aspx

20 (potential) issue of 64bit porting: http://www.viva64.com/en/a/0004/

GCC Type Attributes: http://gcc.gnu.org/onlinedocs/gcc-3.2.3/gcc/Type-Attributes.html

The 3rd link isn’t really important, but to be sure I set the “packed” property on a potentially dangerous union type (pointer and int overlay, though I removed the pointer).

The main issue with my code was my use of size_t. I use it everywhere! That’s not a bad thing, but I also use it inside my container types. That’s also not a bad thing, but these container types are designed to be bulk-written to disk as-is, which I do in some of my file formats.

struct DataBlock {
	size_t Size;
	char Data[0];
};

That was the main culprit right there. Many of my datafiles contain raw DataBlock data (streams of memory, 32bit size followed by data). As it turns out, size_t is 64bits on 64bit OS’s, causing all kinds of alignment issues. Hoo boy!

My response to this was to create my own size_t: st for the system version (size_t), st32 for a 32bit size holding type (unsigned int), and st64 for a 64bit size holding type (unsigned long long int).

struct DataBlock {
	st32 Size; // NOT size_t due to 64bit compatibility //
	char Data[0];
};

Ahh, much better.

I’m not too concerned about the 32bit limit on the size of a DataBlock. That lets me store and allocate just under 4GB of data in one. I may some day add a DataBlock64 type, but there’s no good reason right now (maintaining code that will never be used = waste of time).

As for other bugs going 64bit: On Linux, when I enabled GLee (the OpenGL extension library, not the musical), it introduced a number of new symbols that conflicted with my code (Thanks X Windows headers!). Bool, Status, and Font. I had to rename a bunch of variables and types to fix that.

Aside from that, the 64bit Linux build is consistently detecting a double-free I’m doing on exit. That one has plagued me for a while (rarely ever caused problems), so I’m glad I now have a platform that does it every time.

That’s all for tonight.