3

Using the new Xcode 8 GM build on the GM of macOS Sierra, I've recompiled a Qt 5.7 C++ project and I'm getting the following error message when trying to launch the app:

Reason: no suitable image found. Did find:

/path/to/my/lib/libio_core.dylib: malformed mach-o image: symbol table underruns __LINKEDIT

This doesn't occur on debug builds, only release. Does anyone have an idea as to what this means and how to go about fixing it?


Update:

This actually has nothing to do with Xcode 8. Building the same code with Xcode 7.3.1 results in the same outcome. It seems some apps that ran just fine on El Capitan won't run on Sierra and fail with the above error.


Update 2: Details about the symbol table in my binary:

Load command 5
     cmd LC_SYMTAB
 cmdsize 24
  symoff 0
   nsyms 0
  stroff 12760
 strsize 8
Tim
  • 4,560
  • 2
  • 40
  • 64
  • It seems that they added a new check to the version of `dyld` that ships with Sierra. Apparently, some of the Mach-O binaries found in the wild do not pass the check for whatever reason. Currently I have no clue _why_ those binaries become malformed and even what this “underruns” means. I guess, we’ll have to wait for Apple to release the sources of the new `dyld` to at least understand what is the check. – kirelagin Sep 09 '16 at 11:49

2 Answers2

5

Turns out this was caused by Qt. Qt 5.7.0 calls strip with no arguments when performing the install task on libs. With macOS Sierra this results in a dylib with an empty symtab.

This bug will be fixed in Qt 5.7.1. In the meantime, just make sure you call strip with -S -x for dynamic libraries.

Tim
  • 4,560
  • 2
  • 40
  • 64
3

I am seeing a similar error and I have just figured it out in my case. I hope what I found will help you too.

So, basically, as far as I can tell, this happens when your binary has an empty symbol table (there might be other cases, though). You can check this by running objdump -private-headers <library>:

<...>
Load command 4
     cmd LC_SYMTAB
 cmdsize 24
  symoff 0
   nsyms 0        <-- no symbols, oops
  stroff 4104
 strsize 8
<...>

Linker believes that if the symbol table is empty (nsyms 0) it is ok to say that the offset of the table into the file is zero (symoff 0). So, strictly speaking, it claims that the table starts right at the beginning of the binary.

Apparently, the new version of dyld from 10.12 Sierra performs a check that previous versions did not perform: it makes sure that the symbols table is entirely within the __LINKEDIT segment. Well, in our case the symbol table clearly violates this constraint and dyld does not care that it is empty.


I would call this an Apple’s bug: their linker creates malformed binaries and doesn’t bother to even issue a warning. If I were Apple, I would modify the condition in dyld to ignore the symbol table constraint if the symbol table is empty.

There is only one workaround I can see: add a dummy symbol to your reexport library.

kirelagin
  • 13,248
  • 2
  • 42
  • 57
  • Speaking specifically about your question: it’s hard to tell where does the offending library come from in your case. If it is a Qt library, you might try to report it to them. – kirelagin Sep 09 '16 at 13:47
  • I'm not sure if it is Qt library issue or mine. – Tim Sep 09 '16 at 15:25
  • Apparently `objdump` is not longer included in Xcode. – Tim Sep 09 '16 at 15:30
  • @Tim Very strange, as it is actually _the new_ utility, which replaced `otool`. You can use `otool -l ` instead. – kirelagin Sep 09 '16 at 15:43
  • looks like my binary has much the same problem as yours. I don't believe it is related to `Qt` since other `dylibs` in the same project are fine. I'm wondering if I'm somehow invoking `strip` incorrectly. – Tim Sep 09 '16 at 15:55
  • @Tim In my case reexporting was the cause. We create a library (empty by itself) which just reexports a bunch of other libraries by a call of the form `ld -o new.dylib -reexport_library old.dylib`. The new library has no symbols of its own and there you go. I’m just saying that there might be multiple ways to end up with a library without local symbols, not just `strip`. – kirelagin Sep 09 '16 at 16:00