Skip to content

lld crash with Wl,-fixup_chains when build ios #94716

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
liudikang opened this issue Jun 7, 2024 · 6 comments · Fixed by #97156
Closed

lld crash with Wl,-fixup_chains when build ios #94716

liudikang opened this issue Jun 7, 2024 · 6 comments · Fixed by #97156
Assignees

Comments

@liudikang
Copy link

What did you do?

First we build a go project with gomobile (https://github.com/xxf098/go-tun2socks-build) as a static library,
then linker this static library into our IOS project.

What did you see happen?
lld crashed.

I found crash position of lld:

SymtabSectionImpl<LP>::writeTo of file lld/MachO/SyntheticSections.cpp
Crashed on this line: nList->n_sect = defined->isec()->parent->index;

After we remove ldflags "-Wl,-fixup_chains" ,or modify llvm code crash not happed.

this is crash stack (this lld is build by myself,prebuild is same)

 #0 0x0000000104b0d454 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/xxxxx/third_party/llvm-build/Release+Asserts/bin/lld+0x1000fd454)
 #1 0x0000000104b0b664 llvm::sys::RunSignalHandlers() (/xxxxx/third_party/llvm-build/Release+Asserts/bin/lld+0x1000fb664)
 #2 0x0000000104b0db10 SignalHandler(int) (/xxxxx/third_party/llvm-build/Release+Asserts/bin/lld+0x1000fdb10)
 #3 0x000000019c48b584 (/usr/lib/system/libsystem_platform.dylib+0x180477584)
 #4 0x0000000104e17154 SymtabSectionImpl<lld::macho::LP64>::writeTo(unsigned char*) const (/xxxxx/third_party/llvm-build/Release+Asserts/bin/lld+0x100407154)
 #5 0x0000000104a948b8 std::__1::__function::__func<llvm::parallelFor(unsigned long, unsigned long, llvm::function_ref<void (unsigned long)>)::$_1, std::__1::allocator<llvm::parallelFor(unsigned long, unsigned long, llvm::function_ref<void (unsigned long)>)::$_1>, void ()>::operator()() (/xxxxx/third_party/llvm-build/Release+Asserts/bin/lld+0x1000848b8)
 #6 0x0000000104a947d0 std::__1::__function::__func<llvm::parallel::TaskGroup::spawn(std::__1::function<void ()>, bool)::$_0, std::__1::allocator<llvm::parallel::TaskGroup::spawn(std::__1::function<void ()>, bool)::$_0>, void ()>::operator()() (/xxxxx/third_party/llvm-build/Release+Asserts/bin/lld+0x1000847d0)
 #7 0x0000000104a93270 llvm::parallel::detail::(anonymous namespace)::ThreadPoolExecutor::work(llvm::ThreadPoolStrategy, unsigned int) (/xxxxx/third_party/llvm-build/Release+Asserts/bin/lld+0x100083270)
 #8 0x0000000104a92fac void* std::__1::__thread_proxy[abi:un170006]<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct>>, llvm::parallel::detail::(anonymous namespace)::ThreadPoolExecutor::ThreadPoolExecutor(llvm::ThreadPoolStrategy)::'lambda'()>>(void*) (/xxxxx/third_party/llvm-build/Release+Asserts/bin/lld+0x100082fac)
 #9 0x000000019c45af94 (/usr/lib/system/libsystem_pthread.dylib+0x180446f94)
@github-actions github-actions bot added the lld label Jun 7, 2024
@MaskRay MaskRay added lld:MachO and removed lld labels Jun 7, 2024
@llvmbot
Copy link
Member

llvmbot commented Jun 7, 2024

@llvm/issue-subscribers-lld-macho

Author: None (liudikang)

## What did you do? First we build a go project with gomobile (https://github.com/xxf098/go-tun2socks-build) as a static library, then linker this static library into our IOS project.

What did you see happen?
lld crashed.

I found crash position of lld:

SymtabSectionImpl&lt;LP&gt;::writeTo of file lld/MachO/SyntheticSections.cpp
Crashed on this line: nList-&gt;n_sect = defined-&gt;isec()-&gt;parent-&gt;index;

After we remove ldflags "-Wl,-fixup_chains" ,or modify llvm code crash not happed.

this is crash stack (this lld is build by myself,prebuild is same)

 #<!-- -->0 0x0000000104b0d454 llvm::sys::PrintStackTrace(llvm::raw_ostream&amp;, int) (/xxxxx/third_party/llvm-build/Release+Asserts/bin/lld+0x1000fd454)
 #<!-- -->1 0x0000000104b0b664 llvm::sys::RunSignalHandlers() (/xxxxx/third_party/llvm-build/Release+Asserts/bin/lld+0x1000fb664)
 #<!-- -->2 0x0000000104b0db10 SignalHandler(int) (/xxxxx/third_party/llvm-build/Release+Asserts/bin/lld+0x1000fdb10)
 #<!-- -->3 0x000000019c48b584 (/usr/lib/system/libsystem_platform.dylib+0x180477584)
 #<!-- -->4 0x0000000104e17154 SymtabSectionImpl&lt;lld::macho::LP64&gt;::writeTo(unsigned char*) const (/xxxxx/third_party/llvm-build/Release+Asserts/bin/lld+0x100407154)
 #<!-- -->5 0x0000000104a948b8 std::__1::__function::__func&lt;llvm::parallelFor(unsigned long, unsigned long, llvm::function_ref&lt;void (unsigned long)&gt;)::$_1, std::__1::allocator&lt;llvm::parallelFor(unsigned long, unsigned long, llvm::function_ref&lt;void (unsigned long)&gt;)::$_1&gt;, void ()&gt;::operator()() (/xxxxx/third_party/llvm-build/Release+Asserts/bin/lld+0x1000848b8)
 #<!-- -->6 0x0000000104a947d0 std::__1::__function::__func&lt;llvm::parallel::TaskGroup::spawn(std::__1::function&lt;void ()&gt;, bool)::$_0, std::__1::allocator&lt;llvm::parallel::TaskGroup::spawn(std::__1::function&lt;void ()&gt;, bool)::$_0&gt;, void ()&gt;::operator()() (/xxxxx/third_party/llvm-build/Release+Asserts/bin/lld+0x1000847d0)
 #<!-- -->7 0x0000000104a93270 llvm::parallel::detail::(anonymous namespace)::ThreadPoolExecutor::work(llvm::ThreadPoolStrategy, unsigned int) (/xxxxx/third_party/llvm-build/Release+Asserts/bin/lld+0x100083270)
 #<!-- -->8 0x0000000104a92fac void* std::__1::__thread_proxy[abi:un170006]&lt;std::__1::tuple&lt;std::__1::unique_ptr&lt;std::__1::__thread_struct, std::__1::default_delete&lt;std::__1::__thread_struct&gt;&gt;, llvm::parallel::detail::(anonymous namespace)::ThreadPoolExecutor::ThreadPoolExecutor(llvm::ThreadPoolStrategy)::'lambda'()&gt;&gt;(void*) (/xxxxx/third_party/llvm-build/Release+Asserts/bin/lld+0x100082fac)
 #<!-- -->9 0x000000019c45af94 (/usr/lib/system/libsystem_pthread.dylib+0x180446f94)

@BertalanD BertalanD self-assigned this Jun 7, 2024
@BertalanD
Copy link
Member

Thank you for the report. Could you create a standalone reproducer tarball by executing ld64.lld with the LLD_REPRODUCE=repro.tar environment variable set?

@liudikang
Copy link
Author

this file is too large,I don’t have enough time to deal it today. I'll deal with it on Tue.

@BertalanD
Copy link
Member

Uploading it to Google Drive or another cloud file sharing platform should be enough.

@liudikang
Copy link
Author

https://drive.google.com/file/d/121YoHilR-I7jJFM5Clpcu4HaRS0W3JL2/view?usp=sharing

BertalanD added a commit to BertalanD/llvm-project that referenced this issue Jun 29, 2024
When `-fixup_chains`/`-init_offsets` is used, a different section,
`__init_offsets` is synthesized from `__mod_init_func`. If there are any
symbols defined inside `__mod_init_func`, they are added to the symbol
table unconditionally while processing the input files. Later, when
querying these symbols' addresses (when constructing the symtab or
exports trie), we crash with a null deref, as there is no output
section assigned to them.

Just making the symbols point to `__init_offsets` is a bad idea, as the
new section stores 32-bit integers instead of 64-bit pointers; accessing
the symbols would not do what the programmer intended. We should
entirely omit them from the output. This is what ld64 and ld-prime do.

This patch uses the same mechanism as dead-stripping to mark these
symbols as not needed in the output. There might be nicer fixes than the
workaround, this is discussed in llvm#97155.

Fixes llvm#79894 (comment)
Fixes llvm#94716
BertalanD added a commit to BertalanD/llvm-project that referenced this issue Jun 29, 2024
The repro file in llvm#94716 contains a few thin archives without their
member object files present. I couldn't figure out why this happened
(issue in repro tarball generation?), but this caused an "unhandled
Error" crash on `LLVM_ENABLE_ABI_BREAKING_CHECKS` builds.
@BertalanD
Copy link
Member

Hello! I'm working on a fix for your issue, it should be ready very soon.

There is a pretty strange issue with your repro file, though. It seems to contain thin archives that reference files that don't actually exist anywhere:

$ llvm-ar t Users/snqu/Desktop/chromium/chromium/src/out/Debug-iphoneos/ios_clang_arm64_app_ext/obj/base/libbase.a

Users/snqu/Desktop/chromium/chromium/src/out/Debug-iphoneos/ios_clang_arm64_app_ext/obj/base/base/allocator_check.o
Users/snqu/Desktop/chromium/chromium/src/out/Debug-iphoneos/ios_clang_arm64_app_ext/obj/base/base/dispatcher.o
[...] snip [...]

None of these exist (the paths are relative to the extracted repro tarball's root directory). This causes an assertion failure in LLD that's built in debug mode (#97169). I'm working on creating a fix for that; could you help me figure out how the issue can be reproduced? Answering these would be very helpful:

  • Do the mentioned object files exist on your computer?
  • How were they created? If the whole code base is open source (not just the go library), how do I build it locally?

BertalanD added a commit that referenced this issue Jul 6, 2024
…97156)

When `-fixup_chains`/`-init_offsets` is used, a different section,
`__init_offsets` is synthesized from `__mod_init_func`. If there are any
symbols defined inside `__mod_init_func`, they are added to the symbol
table unconditionally while processing the input files. Later, when
querying these symbols' addresses (when constructing the symtab or
exports trie), we crash with a null deref, as there is no output section
assigned to them.

Just making the symbols point to `__init_offsets` is a bad idea, as the
new section stores 32-bit integers instead of 64-bit pointers; accessing
the symbols would not do what the programmer intended. We should
entirely omit them from the output. This is what ld64 and ld-prime do.

This patch uses the same mechanism as dead-stripping to mark these
symbols as not needed in the output. There might be nicer fixes than the
workaround, this is discussed in #97155.

Fixes #79894 (comment)
Fixes #94716
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants