MonoGame.Dependencies
MonoGame.Dependencies copied to clipboard
/FreeImage.NET/MacOS/libfreeimage.dylib contains Intel AVX instructions, causing SIGILL signal
When I try building my content using Pipeline.app, I receive this error:
Build started 9/26/2015 9:16:58 AM
/Users/wjl/Projects/testfna/testfna/Content/icon.bmp
/Users/wjl/Projects/testfna/testfna/Content/icon.bmp: error: Importer 'TextureImporter' had unexpected failure!
System.ExecutionEngineException: SIGILL
at Microsoft.Xna.Framework.Content.Pipeline.ContentImporter`1[Microsoft.Xna.Framework.Content.Pipeline.Graphics.TextureContent].Microsoft.Xna.Framework.Content.Pipeline.IContentImporter.Import (System.String filename, Microsoft.Xna.Framework.Content.Pipeline.ContentImporterContext context) [0x00000] in <filename unknown>:0
at MonoGame.Framework.Content.Pipeline.Builder.PipelineManager.ProcessContent (MonoGame.Framework.Content.Pipeline.Builder.PipelineBuildEvent pipelineEvent) [0x00000] in <filename unknown>:0
Build 0 succeeded, 1 failed.
Time elapsed 00:00:00.25.
When debugging with lldb, I found that the illegal instruction was located in libfreeimage.dylib:
$ lldb mono
(lldb) target create "mono"
Current executable set to 'mono' (i386).
(lldb) process launch /Users/wjl/Projects/MonoGame/Tools/MGCB/bin/MacOS/AnyCPU/Debug/MGCB.exe /@:/Users/wjl/Projects/testfna/testfna/Content/Content.mgcb
Process 9666 launched: '/usr/local/bin/mono' (i386)
warning: (i386) /Library/Frameworks/Mono.framework/Versions/4.0.4/lib/mono/4.5/mscorlib.dll.dylib empty dSYM file detected, dSYM was created with an executable with no debug info.
Build started 9/26/2015 9:30:15 AM
/Users/wjl/Projects/testfna/testfna/Content/icon.bmp
Process 9666 stopped
* thread #1: tid = 0xc5d7ae, 0x03148297 libfreeimage.dylib`TagLib::TagLib() + 21, queue = 'com.apple.main-thread', stop reason = EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
frame #0: 0x03148297 libfreeimage.dylib`TagLib::TagLib() + 21
libfreeimage.dylib`TagLib::TagLib() + 21:
-> 0x3148297: vxorps %xmm0, %xmm0, %xmm0
0x314829b: vmovups %xmm0, 0x4(%esi)
0x31482a0: movl $0x0, 0x14(%esi)
0x31482a7: movl %eax, 0xc(%esi)
(lldb)
The vxorps
instruction is an Intel AVX instruction that is not supported on older chips. According to wikipedia, the AVX extension was introduced in 2011, so any chip older than that doesn't support the extension.
To work around this problem, I used homebrew to compile libfreeimage.dylib from source and replaced the dylib in the .app with the freshly compiled homebrew version:
$ brew install freeimage --build-from-source --universal
==> Downloading https://downloads.sourceforge.net/project/freeimage/Source%20Distribution/3.17.0/FreeImage3170.zip
==> Downloading from http://iweb.dl.sourceforge.net/project/freeimage/Source%20Distribution/3.17.0/FreeImage3170.zip
######################################################################## 100.0%
==> Patching
patching file Makefile.fip
Hunk #4 succeeded at 69 with fuzz 2.
patching file Makefile.gnu
==> make -f Makefile.gnu
==> make -f Makefile.gnu install PREFIX=/usr/local/Cellar/freeimage/3.17.0
==> make -f Makefile.fip
==> make -f Makefile.fip install PREFIX=/usr/local/Cellar/freeimage/3.17.0
🍺 /usr/local/Cellar/freeimage/3.17.0: 7 files, 65M, built in 4.2 minutes
$
Also, I don't know if any other binaries in this project contain AVX instructions, this is the first time I've ever used this software and I was following a tutorial on how to load an image.
@dellis1972 @KonajuGames - Did we just build FreeImage with the wrong build settings for Mac?
Yeah, it's not a bug in the FreeImage source code. The compiler must have been set to target a CPU that supports those instructions, and my Core 2 Duo doesn't support those instructions.
I think the original libfreeimage.dylib was sourced from home-brew..
first the 64 bit version was downloaded.. then the 32 bit then they were merged to provide a universal binary.
Looks like @KonajuGames https://github.com/KonajuGames modified it recently , not sure how that was compiled/ put together.
On 26 September 2015 at 19:55, wjlandryiii [email protected] wrote:
Yeah, it's not a bug in the FreeImage source code. The compiler must have been set to target a CPU that supports those instructions, and my Core 2 Duo doesn't support those instructions.
— Reply to this email directly or view it on GitHub https://github.com/Mono-Game/MonoGame.Dependencies/issues/61#issuecomment-143479460 .
My Mac is from 2010, and there was nothing special with building it. The makefile provided with FreeImage specifies i386 and x86_64 as the CPU targets. I'll have a closer look.
I think I figured it out.
It looks like when you compile from source, homebrew will check the hardware you are compiling on and set compiler flags to optimize for that specific hardware. To disable the automatic hardware optimizations, you can use the homebrew command line option --build-bottle
. When building for a bottle, homebrew will use the oldest processor to base it's compiler optimizations on to allow it to run on all hardware.
I bet your 2010 mac supports AVX, and that's why it was compiled that way. You can check if your system supports AVX by running the command sysctl -n hw.optional.avx1_0
. "0" means the hardware does not support AVX, while "1" means the hardward does support AVX.
I tried this on a mac I have access to that supports AVX. Here is the proof that it works:
MiniDVR:~ minidvr$ brew install freeimage --build-from-source --universal
==> Downloading https://downloads.sourceforge.net/project/freeimage/Source%20Distribution/3.17.0/FreeImage3170.zip
Already downloaded: /Library/Caches/Homebrew/freeimage-3.17.0.zip
==> Patching
patching file Makefile.fip
Hunk #4 succeeded at 69 with fuzz 2.
patching file Makefile.gnu
==> make -f Makefile.gnu
==> make -f Makefile.gnu install PREFIX=/usr/local/Cellar/freeimage/3.17.0
==> make -f Makefile.fip
==> make -f Makefile.fip install PREFIX=/usr/local/Cellar/freeimage/3.17.0
🍺 /usr/local/Cellar/freeimage/3.17.0: 7 files, 63M, built in 107 seconds
MiniDVR:~ minidvr$ otool -arch i386 -tv /usr/local/Cellar/freeimage/3.17.0/lib/libfreeimage.dylib | grep vxorps | head
00004922 vxorps %ymm0, %ymm0, %ymm0
00004f74 vxorps %xmm0, %xmm0, %xmm0
00006525 vxorps %ymm0, %ymm0, %ymm0
00008f6b vxorps %ymm0, %ymm0, %ymm0
0000a8ae vxorps %xmm0, %xmm0, %xmm0
0000d116 vxorps %xmm0, %xmm0, %xmm0
0000d702 vxorps %ymm0, %ymm0, %ymm0
0000d8eb vxorps %ymm0, %ymm0, %ymm0
0000e115 vxorps %xmm0, %xmm0, %xmm0
0000e67b vxorps %xmm0, %xmm0, %xmm0
MiniDVR:~ minidvr$ brew remove freeimage
Uninstalling /usr/local/Cellar/freeimage/3.17.0... (7 files, 63M)
MiniDVR:~ minidvr$ brew install freeimage --build-from-source --universal --build-bottle
==> Downloading https://downloads.sourceforge.net/project/freeimage/Source%20Distribution/3.17.0/FreeImage3170.zip
Already downloaded: /Library/Caches/Homebrew/freeimage-3.17.0.zip
==> Patching
patching file Makefile.fip
Hunk #4 succeeded at 69 with fuzz 2.
patching file Makefile.gnu
==> make -f Makefile.gnu
==> make -f Makefile.gnu install PREFIX=/usr/local/Cellar/freeimage/3.17.0
==> make -f Makefile.fip
==> make -f Makefile.fip install PREFIX=/usr/local/Cellar/freeimage/3.17.0
🍺 /usr/local/Cellar/freeimage/3.17.0: 7 files, 63M, built in 107 seconds
MiniDVR:~ minidvr$ otool -arch i386 -tv /usr/local/Cellar/freeimage/3.17.0/lib/libfreeimage.dylib | grep vxorps | head
MiniDVR:~ minidvr$
@dellis1972 - Is this still a thing we need to fix or can we close this?
We should probably update free image net with this stuff. That said our min MacOS is 10.7 now for the Pipeline tool, not sure that will even run on a machine that old?