[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Crash in ___lldb_unnamed_symbol / cannot locate symbol "__start___ob
From: |
David Chisnall |
Subject: |
Re: Crash in ___lldb_unnamed_symbol / cannot locate symbol "__start___objc_selectors" on Android |
Date: |
Mon, 1 Jul 2019 16:24:21 +0100 |
User-agent: |
Mozilla/5.0 (Windows NT 10.0; WOW64; rv:60.0) Gecko/20100101 Thunderbird/60.7.2 |
Hi,
On 01/07/2019 15:38, Frederik Seiffert wrote:
Thanks for the explanation David.
I believe there was a bug in clang where I didn't add an empty symbol
for compilation units that didn't contain any selectors. If you then
linked a program or a library that didn't contain any selectors then
you'd see this error at link time. This should now be fixed, but you
can work around it by making sure that at least one of the
Objective-C[++] files that you link includes at least one use of a
selector.
After skimming CGObjCGNU.cpp in Clang I had the exact same thought, but
I had only added ObjC code/selectors, not ObjC++. After adding both the
app links fine. (Btw. I don’t think CGObjCGNU.cpp
<https://github.com/llvm-mirror/clang/blob/master/lib/CodeGen/CGObjCGNU.cpp#L927-L939> currently
emits empty symbols for selectors if none are found, only for protocols
and classes).
It does:
https://github.com/llvm-mirror/clang/blob/44f7b2cea9a2ae54023740cf1a8c067d6b0e090a/lib/CodeGen/CGObjCGNU.cpp#L1603
Though I'm not sure if that has always been working.
However, now the Qt app also fails with the same backtrace as the one in
Android Studio (issue #2 from my original email), but Qt’s debugger is
showing me more info and think I have an idea about what’s going on now.
I think for some reason objc_send_initialize() is being called on
classes before Objective C categories have been loaded. This causes
various unrecognized selector calls because many internal functions in
GNUstep are implemented in categories (e.g. NSObject (GNUstepBase)). In
my specific stack trace, +[NSException raise:format:arguments:] was
calling +[NSString stringWithFormat:arguments:] (implemented in the
GNUstepBase NSString category), causing another exception ad infinitum.
Replacing that NSString call in NSException with a non-category version
causes it to crash in various other initializers calling category methods.
The way in which things are loaded is defined here (for the v2 ABI, the
v1 ABI loads things one compilation unit at a time):
https://github.com/gnustep/libobjc2/blob/d16faeded958f94033092631b6988fb15654f995/loader.c#L189
For any binary, the runtime will:
1. Load all selectors and register them.
2. Load all protocols and register / unique them.
3. Load all references to protocols and update them to point to the
canonical definition of the protocol.
4. Load all classes and resolve them.
5. Load all categories and resolve them.
5. Send +load to any classes that support them.
7. Register any class aliases.
The only ways that you can end up with a +initialize method being called
before a category is resolved are:
- If it's in an __attribute__((constructor)) function or a C++ global
initialiser that's called before Objective-C runtime init (except on
Windows, where these are guaranteed to happen in the right order).
- If the code calling it is in a different library to the category.
I know on Apple platforms one must pass -all_load or -force_load to the
linker to use categories in static libraries, but this doesn’t seem to
be recognized by my linker (and doesn’t seem to be necessary for other
ABIs). Is there anything else that might be going on here?
Apple's implementation is very different and is deeply coupled with
their linker and loader.
Looking at your backtrace, it appears that you're seeing the bug in BFD
ld. With the -r option, it resolved the __start and __stop symbols
early, then ended up with a .o file that caused everything declared in
it to be dropped during final linkage. This results in anything in the
GNUstep Base Additions library being discarded. Linking GNUstep Base
(and -base Additions) with either lld or gold should fix this problem.
David