OS X: Crash running program compiled on a different Mac

totalgee wrote on Wednesday, September 17, 2014:

Hi there, my development machine is a MacBook Air (OS X 10.9.4). I compiled a simple test program using the static GLFW 3.0.4 library (installed using brew install --static glfw3) with Xcode 5.1.1.

When I copy even the simplest test program to another machine (an older iMac with Radeon 4670 graphics, but also running OS X 10.9.4), it crashes with the following message:

Illegal instruction: 4

The crash happens during the glfwInit() call. I can’t get more details or a stack trace, because I don’t have developer tools installed on the “user” machine (I want it to be a non-dev machine, on which I can test-deploy my app). I know that the Radeon 4670 only supports up to OpenGL 3.3 under OS X 10.9, but since I haven’t even gotten to the point of creating a window/context, I think that’s irrelevant.

Anyone have any ideas on how to proceed? Again, both machines are running OS X 10.9.4. One is an i5, the other an older i3.

Thanks,
Glen.

P.S. My “simplest test program” can be just:

#include <GLFW/glfw3.h>
int main()
{
    glfwInit();
    glfwTerminate();
    return 0;
}

And to compile:

c++ -o test test.cpp -lglfw3 -framework Cocoa -framework OpenGL -framework IOKit -framework CoreVideo

totalgee wrote on Wednesday, September 17, 2014:

I managed to run the program on another OS X 10.9.4 machine (also an older iMac, but with developer tools installed). Using gdb, I was at least able to see that the crash is in _glfwPlatformInit() (EXC_BAD_INSTRUCTION, Illegal instruction/operand), called by glfwInit().

Does this mean that my brew version of GLFW is using (OS or CPU) features that are not available on slightly older machines?

elmindreda wrote on Wednesday, September 17, 2014:

That’s possible, depending on what flags were used for compilation.

totalgee wrote on Wednesday, September 17, 2014:

Okay, seems I’ve figured this out (not the exact cause, but at least a solution!). Seems I was barking up the wrong tree, at least a bit. I had copied the executable onto a memory stick that was FAT32 formatted, so it didn’t keep the OS X permissions (and possibly other file metadata?). Even though the file was executable on the other OS X machine, somehow it didn’t work, always crashing on glfwInit(). Something got “lost” in the copy.

If I tar up the file and transfer it that way, it no longer crashes.

elmindreda wrote on Thursday, September 18, 2014:

Interesting bug. Thank you for the follow-up!

totalgee wrote on Tuesday, November 04, 2014:

Well, I spoke too soon. I am still having the original problem (crash with Illegal instruction: 4). It happens when running a simple test program (such as the one above), now compiled on a 10.9.5 machine and trying to run on a non-developer 10.9.5 machine. It happens even when I tar up the file and it has correct permissions.

Any ideas where else I could look? I’m linking with the static libglfw3.a, installed using brew. I’m now using Xcode 6.1 (i.e. compiling with Apple LLVM version 6.0 (clang-600.0.54)). I tried uninstalling and reinstalling glfw3, so that it is also built and linked with the same version of the compiler, but it doesn’t solve the crash.

elmindreda wrote on Tuesday, November 04, 2014:

Have you looked at these threads?

totalgee wrote on Tuesday, November 04, 2014:

Thanks for the links, it’s helpful to learn more debugging tricks (like dtruss). I’ve tried various suggested things, such as compiling with -mmacosx-version-min=10.6 (which doesn’t make much sense, since all my machines are on the same OS revision).

In the end, I discovered that if I compile on a MacBook Air, it runs fine on the slightly older iMac (all machines running 10.9.5). The problem occurs when I compile on a new Mac Pro and try to run on the iMac. Something to do with the architecture? In both cases, running file on the executable indicates

test: Mach-O 64-bit executable x86_64

I’ve tried building a universal version of GLFW, and my app, on the Mac Pro (Xeon E5), but it still crashes when running on the other machine (Core i3). I even tried compiling/linking both GLFW and my program with -arch i386 for the 32-bit version, and it still gives me the Illegal instruction: 4 error with the executable built on the Mac Pro!

Do some Xeon-only optimisations get enabled by default with the compiler? How do I turn them off?

totalgee wrote on Wednesday, November 05, 2014:

Further update: it works if I build GLFW locally (not using brew), then link with that static library.

It always crashes (in _glfwPlatformInit()) with a brew-built glfw3 version (built on my Mac Pro, test program running on an older iMac). The compilation and linking flags for both brew and regular cmake runs look the same… Mystified.

elmindreda wrote on Wednesday, November 05, 2014:

This is not related to GLFW, then, but to instruction set compiler flags vs. an old CPU.

totalgee wrote on Wednesday, November 05, 2014:

Thanks, Camilla, you’re right (but the problem was I didn’t know how to fix it). I got a reply from the brew folks, though, and now the problem is solved. I needed to build/install GLFW using their “build-bottle” option, which builds projects using a more compatible set of flags:

$ brew install glfw3 --static --build-bottle

This solves my crash. If anyone is interested, the answer is here.

elmindreda wrote on Wednesday, November 05, 2014:

Thank you for the follow-up! I’ll find a place for this in the documentation.