-
Notifications
You must be signed in to change notification settings - Fork 13.3k
miscompiled TLS wrapper, likely coroutine related, with sanitizer #91312
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Comments
Copying @dianqk, the author of the patch. |
another data point is that if the source is compiled with |
Reproducer: wget https://scratch.scylladb.com/schema_tables.ii
clang++ -MD -MT build/debug/db/schema_tables.o -MF build/debug/db/schema_tables.o.d -std=c++20 -I/home/avi/scylla/seastar/include -I/home/avi/scylla/build/debug/seastar/gen/include -U_FORTIFY_SOURCE -Werror=unused-result -fstack-clash-protection -fsanitize=address -fsanitize=undefined -fno-sanitize=vptr -DSEASTAR_API_LEVEL=7 -DSEASTAR_BUILD_SHARED_LIBS -DSEASTAR_SSTRING -DSEASTAR_LOGGER_COMPILE_TIME_FMT -DSEASTAR_SCHEDULING_GROUPS_COUNT=16 -DSEASTAR_DEBUG -DSEASTAR_DEFAULT_ALLOCATOR -DSEASTAR_SHUFFLE_TASK_QUEUE -DSEASTAR_DEBUG_SHARED_PTR -DSEASTAR_DEBUG_PROMISE -DSEASTAR_LOGGER_TYPE_STDOUT -DSEASTAR_TYPE_ERASE_MORE -DFMT_SHARED -I/usr/include/p11-kit-1 -ffile-prefix-map=/home/avi/scylla=. -march=westmere -DDEBUG -DSANITIZE -DDEBUG_LSA_SANITIZER -DSCYLLA_ENABLE_ERROR_INJECTION -Og -DSCYLLA_BUILD_MODE=debug -g -gz -iquote. -iquote build/debug/gen -std=gnu++20 -ffile-prefix-map=/home/avi/scylla=. -march=westmere -DBOOST_ALL_DYN_LINK -fvisibility=hidden -isystem abseil -Wall -Werror -Wextra -Wimplicit-fallthrough -Wno-mismatched-tags -Wno-c++11-narrowing -Wno-overloaded-virtual -Wno-unused-parameter -Wno-unsupported-friend -Wno-missing-field-initializers -Wno-deprecated-copy -Wno-psabi -Wno-enum-constexpr-conversion -Wno-error=deprecated-declarations -DXXH_PRIVATE_API -DSEASTAR_TESTING_MAIN -S schema_tables.ii -o schema_tables.s
grep -A10 '_ZTWN2db13schema_tablesL14the_merge_lockE.*:' schema_tables.s |
Thanks. I can reproduce it. The bisected outcome might not be the issue itself, but I'll investigate this first. |
Simplified command line: clang++ -fsanitize=address -Og -std=gnu++20 -Wno-c++11-narrowing -Wno-unsupported-friend -S schema_tables.ii -o schema_tables.s && grep -A10 '_ZTWN2db13schema_tablesL14the_merge_lockE.*:' schema_tables.s I verified that -fsanitize=address is required. |
Yes it's probably coroutines not emitting llvm.used. I remember bugs in this area. |
@llvm/issue-subscribers-coroutines Author: Avi Kivity (avikivity)
Prior to 533b7c1, compiling some coroutine that references a TLS variable generates this wrapper:
0000000000029d80 <_ZTWN2db13schema_tablesL14the_merge_lockE>:
29d80: 50 pushq %rax
29d81: e8 4a b3 10 00 callq 0x1350d0 <__tls_init>
29d86: 64 48 8b 04 25 00 00 00 00 movq %fs:0x0, %rax
29d8f: 48 8d 80 00 00 00 00 leaq (%rax), %rax
0000000000029d92: R_X86_64_TPOFF32 _ZN2db13schema_tablesL14the_merge_lockE
29d96: 59 popq %rcx
29d97: c3 retq
29d98: 0f 1f 84 00 00 00 00 00 nopl (%rax,%rax) It correctly calls With 533b7c1 and later, up to 18.1.1, the following TLS wrapper is generated: 0000000000029d80 <_ZTWN2db13schema_tablesL14the_merge_lockE>:
29d80: 50 pushq %rax
29d81: e8 00 00 00 00 callq 0x29d86 <_ZTWN2db13schema_tablesL14the_merge_lockE+0x6>
0000000000029d82: R_X86_64_PLT32 _ZTH15data_type_for_vIN7seastar13basic_sstringIcjLj15ELb1EEEE-0x4
29d86: 64 48 8b 04 25 00 00 00 00 movq %fs:0x0, %rax
29d8f: 48 8d 80 00 00 00 00 leaq (%rax), %rax
0000000000029d92: R_X86_64_TPOFF32 _ZN2db13schema_tablesL14the_merge_lockE
29d96: 59 popq %rcx
29d97: c3 retq
29d98: 0f 1f 84 00 00 00 00 00 nopl (%rax,%rax) The call to I will follow up with a full reproducer. |
It should also need |
I haven't found any obvious issues, unless I missed something.
@_ZTHN2db13schema_tablesL14the_merge_lockE = internal alias void (), ptr @__tls_init
@_ZTH15data_type_for_vIN7seastar13basic_sstringIcjLj15ELb1EEEE = linkonce_odr alias void (), ptr @__tls_init
@_ZTH15data_type_for_vIiE = linkonce_odr alias void (), ptr @__tls_init Perhaps we need a runtime issue reproduction? |
Aha. The runtime reproducer is quite heavy. If you want, I can provide a pre-built docker image and instructions to expose the problem with gdb. |
My guess is that it's related. The compiler lost some information about TLS, so it started aliasing __tls_init to some other function. I'm single-stepping through it now, and I'm seeing that it's not initializing the variable. |
I think what happens is that the guard variable is set when __tls_init (or its alias) is called, so the initializers aren't run. I set a watchpoint on the variable:
So some unrelated __tls_init set it. |
Confirmed. So a local __tls_init is generated, but then another gets called, perhaps due to the aliasing. |
I verified that a binary built before the patch works, and after the patch fails. So the bisection is still accurate. |
diff of the generated assembly: $ diff -u schema_tables.s.full.{good,bad}
--- schema_tables.s.full.good 2024-05-07 20:02:55.038613957 +0300
+++ schema_tables.s.full.bad 2024-05-07 20:50:43.162254156 +0300
@@ -396,7 +396,6 @@
0000000000000f40 l O .rodata 0000000000000060 __PRETTY_FUNCTION__._ZN2db13schema_tables15hold_merge_lockEv
0000000000000000 l d .text._ZN7seastar9get_unitsINS_35semaphore_default_exception_factoryENSt6chrono3_V212steady_clockEEENS_6futureINS_15semaphore_unitsIT_T0_EEEERNS_15basic_semaphoreIS7_S8_EEm 0000000000000000 .text._ZN7seastar9get_unitsINS_35semaphore_default_exception_factoryENSt6chrono3_V212steady_clockEEENS_6futureINS_15semaphore_unitsIT_T0_EEEERNS_15basic_semaphoreIS7_S8_EEm
0000000000003c5a l O .rodata.str1.1 0000000000000039 .L___asan_gen_.4441
-00000000001350d0 l F .text 000000000000011c __tls_init
0000000000000138 l .tbss 0000000000000050 db::schema_tables::the_merge_lock
0000000000003c93 l O .rodata.str1.1 000000000000006b .L___asan_gen_.4442
000000000018d900 l F .text 0000000000000778 db::schema_tables::merge_schema(seastar::sharded<db::system_keyspace>&, seastar::sharded<service::storage_proxy>&, gms::feature_service&, std::vector<mutation, std::allocator<mutation>>, bool) (.resume)
@@ -7220,6 +7219,7 @@
0000000000000000 w F .text._ZN7seastar20noncopyable_functionIFNS_6futureINS_15semaphore_unitsINS_35semaphore_default_exception_factoryENSt6chrono3_V212steady_clockEEEEEvEED2Ev 00000000000000ce .hidden seastar::noncopyable_function<seastar::future<seastar::semaphore_units<seastar::semaphore_default_exception_factory, std::chrono::_V2::steady_clock>> ()>::~noncopyable_function()
0000000000000000 w F .text._ZN7seastar20noncopyable_functionIFNS_6futureINS_15semaphore_unitsINS_35semaphore_default_exception_factoryENSt6chrono3_V212steady_clockEEEEEvEEC2EOSA_ 0000000000000112 .hidden seastar::noncopyable_function<seastar::future<seastar::semaphore_units<seastar::semaphore_default_exception_factory, std::chrono::_V2::steady_clock>> ()>::noncopyable_function(seastar::noncopyable_function<seastar::future<seastar::semaphore_units<seastar::semaphore_default_exception_factory, std::chrono::_V2::steady_clock>> ()>&&)
0000000000000000 w F .text._ZN7seastar6futureIvE14then_impl_nrvoINS_20noncopyable_functionIFNS0_INS_15semaphore_unitsINS_35semaphore_default_exception_factoryENSt6chrono3_V212steady_clockEEEEEvEEESA_EET0_OT_ 00000000000001cd .hidden seastar::future<seastar::semaphore_units<seastar::semaphore_default_exception_factory, std::chrono::_V2::steady_clock>> seastar::future<void>::then_impl_nrvo<seastar::noncopyable_function<seastar::future<seastar::semaphore_units<seastar::semaphore_default_exception_factory, std::chrono::_V2::steady_clock>> ()>, seastar::future<seastar::semaphore_units<seastar::semaphore_default_exception_factory, std::chrono::_V2::steady_clock>>>(seastar::noncopyable_function<seastar::future<seastar::semaphore_units<seastar::semaphore_default_exception_factory, std::chrono::_V2::steady_clock>> ()>&&)
+00000000001350d0 w F .text 000000000000011c .hidden thread-local initialization routine for data_type_for_v<seastar::basic_sstring<char, unsigned int, 15u, true>>
0000000000029da0 g F .text 00000000000019a7 .hidden db::schema_tables::merge_schema(seastar::sharded<db::system_keyspace>&, seastar::sharded<service::storage_proxy>&, gms::feature_service&, std::vector<mutation, std::allocator<mutation>>, bool)
0000000000000000 *UND* 0000000000000000 freeze(std::vector<mutation, std::allocator<mutation>> const&)
0000000000000000 w F .text._ZN7seastar8internal13futurize_baseIvE21make_exception_futureINSt15__exception_ptr13exception_ptrEEENS_6futureIvEEOT_ 00000000000000ca .hidden seastar::future<void> seastar::internal::futurize_base<void>::make_exception_future<std::__exception_ptr::exception_ptr>(std::__exception_ptr::exception_ptr&&)
@@ -57984,7 +57984,8 @@
0000000000029d80 <thread-local wrapper routine for db::schema_tables::the_merge_lock>:
29d80: 50 pushq %rax
- 29d81: e8 4a b3 10 00 callq 0x1350d0 <__tls_init>
+ 29d81: e8 00 00 00 00 callq 0x29d86 <thread-local wrapper routine for db::schema_tables::the_merge_lock+0x6>
+ 0000000000029d82: R_X86_64_PLT32 thread-local initialization routine for data_type_for_v<seastar::basic_sstring<char, unsigned int, 15u, true>>-0x4
29d86: 64 48 8b 04 25 00 00 00 00 movq %fs:0x0, %rax
29d8f: 48 8d 80 00 00 00 00 leaq (%rax), %rax
0000000000029d92: R_X86_64_TPOFF32 db::schema_tables::the_merge_lock
@@ -336033,11 +336034,11 @@
1350c5: 66 2e 0f 1f 84 00 00 00 00 00 nopw %cs:(%rax,%rax)
1350cf: 90 nop
-00000000001350d0 <__tls_init>:
+00000000001350d0 <thread-local initialization routine for data_type_for_v<seastar::basic_sstring<char, unsigned int, 15u, true>>>:
1350d0: 53 pushq %rbx
1350d1: 64 80 3c 25 00 00 00 00 00 cmpb $0x0, %fs:0x0
00000000001350d5: R_X86_64_TPOFF32 __tls_guard
- 1350da: 74 02 je 0x1350de <__tls_init+0xe>
+ 1350da: 74 02 je 0x1350de <thread-local initialization routine for data_type_for_v<seastar::basic_sstring<char, unsigned int, 15u, true>>+0xe>
1350dc: 5b popq %rbx
1350dd: c3 retq
1350de: 64 c6 04 25 00 00 00 00 01 movb $0x1, %fs:0x0
@@ -336047,7 +336048,7 @@
00000000001350f3: R_X86_64_TPOFF32 db::schema_tables::the_merge_lock
1350f7: 48 c1 e8 03 shrq $0x3, %rax
1350fb: 80 b8 00 80 ff 7f 00 cmpb $0x0, 0x7fff8000(%rax)
- 135102: 0f 85 a5 00 00 00 jne 0x1351ad <__tls_init+0xdd>
+ 135102: 0f 85 a5 00 00 00 jne 0x1351ad <thread-local initialization routine for data_type_for_v<seastar::basic_sstring<char, unsigned int, 15u, true>>+0xdd>
135108: 64 48 c7 04 25 00 00 00 00 01 00 00 00 movq $0x1, %fs:0x0
000000000013510d: R_X86_64_TPOFF32 db::schema_tables::the_merge_lock
135115: 64 48 8b 1c 25 00 00 00 00 movq %fs:0x0, %rbx
@@ -336055,13 +336056,13 @@
0000000000135121: R_X86_64_TPOFF32 db::schema_tables::the_merge_lock+0x8
135125: ba 38 00 00 00 movl $0x38, %edx
13512a: 31 f6 xorl %esi, %esi
- 13512c: e8 00 00 00 00 callq 0x135131 <__tls_init+0x61>
+ 13512c: e8 00 00 00 00 callq 0x135131 <thread-local initialization routine for data_type_for_v<seastar::basic_sstring<char, unsigned int, 15u, true>>+0x61>
000000000013512d: R_X86_64_PLT32 __asan_memset-0x4
135131: 48 8d 83 00 00 00 00 leaq (%rbx), %rax
0000000000135134: R_X86_64_TPOFF32 db::schema_tables::the_merge_lock+0x40
135138: 48 c1 e8 03 shrq $0x3, %rax
13513c: 80 b8 00 80 ff 7f 00 cmpb $0x0, 0x7fff8000(%rax)
- 135143: 75 7d jne 0x1351c2 <__tls_init+0xf2>
+ 135143: 75 7d jne 0x1351c2 <thread-local initialization routine for data_type_for_v<seastar::basic_sstring<char, unsigned int, 15u, true>>+0xf2>
135145: 64 48 8b 04 25 00 00 00 00 movq %fs:0x0, %rax
13514e: 48 8d 88 00 00 00 00 leaq (%rax), %rcx
0000000000135151: R_X86_64_TPOFF32 db::schema_tables::the_merge_lock
@@ -336071,37 +336072,37 @@
0000000000135161: R_X86_64_TPOFF32 db::schema_tables::the_merge_lock+0x48
135165: 48 c1 e8 03 shrq $0x3, %rax
135169: 80 b8 00 80 ff 7f 00 cmpb $0x0, 0x7fff8000(%rax)
- 135170: 75 65 jne 0x1351d7 <__tls_init+0x107>
+ 135170: 75 65 jne 0x1351d7 <thread-local initialization routine for data_type_for_v<seastar::basic_sstring<char, unsigned int, 15u, true>>+0x107>
135172: 64 48 c7 04 25 00 00 00 00 00 00 00 00 movq $0x0, %fs:0x0
0000000000135177: R_X86_64_TPOFF32 db::schema_tables::the_merge_lock+0x48
13517f: 64 48 8b 04 25 00 00 00 00 movq %fs:0x0, %rax
135188: 48 8d b0 00 00 00 00 leaq (%rax), %rsi
000000000013518b: R_X86_64_TPOFF32 db::schema_tables::the_merge_lock
- 13518f: 48 8d 3d 00 00 00 00 leaq (%rip), %rdi # 0x135196 <__tls_init+0xc6>
+ 13518f: 48 8d 3d 00 00 00 00 leaq (%rip), %rdi # 0x135196 <thread-local initialization routine for data_type_for_v<seastar::basic_sstring<char, unsigned int, 15u, true>>+0xc6>
0000000000135192: R_X86_64_PC32 seastar::basic_semaphore<seastar::semaphore_default_exception_factory, std::chrono::_V2::steady_clock>::~basic_semaphore()-0x4
- 135196: 48 8d 15 00 00 00 00 leaq (%rip), %rdx # 0x13519d <__tls_init+0xcd>
+ 135196: 48 8d 15 00 00 00 00 leaq (%rip), %rdx # 0x13519d <thread-local initialization routine for data_type_for_v<seastar::basic_sstring<char, unsigned int, 15u, true>>+0xcd>
0000000000135199: R_X86_64_PC32 __dso_handle-0x4
- 13519d: e8 00 00 00 00 callq 0x1351a2 <__tls_init+0xd2>
+ 13519d: e8 00 00 00 00 callq 0x1351a2 <thread-local initialization routine for data_type_for_v<seastar::basic_sstring<char, unsigned int, 15u, true>>+0xd2>
000000000013519e: R_X86_64_PLT32 __cxa_thread_atexit-0x4
- 1351a2: e8 00 00 00 00 callq 0x1351a7 <__tls_init+0xd7>
+ 1351a2: e8 00 00 00 00 callq 0x1351a7 <thread-local initialization routine for data_type_for_v<seastar::basic_sstring<char, unsigned int, 15u, true>>+0xd7>
00000000001351a3: R_X86_64_PLT32 .text.startup+0x28c
1351a7: 5b popq %rbx
- 1351a8: e9 00 00 00 00 jmp 0x1351ad <__tls_init+0xdd>
+ 1351a8: e9 00 00 00 00 jmp 0x1351ad <thread-local initialization routine for data_type_for_v<seastar::basic_sstring<char, unsigned int, 15u, true>>+0xdd>
00000000001351a9: R_X86_64_PLT32 .text.startup+0x2fc
1351ad: 64 48 8b 04 25 00 00 00 00 movq %fs:0x0, %rax
1351b6: 48 8d b8 00 00 00 00 leaq (%rax), %rdi
00000000001351b9: R_X86_64_TPOFF32 db::schema_tables::the_merge_lock
- 1351bd: e8 00 00 00 00 callq 0x1351c2 <__tls_init+0xf2>
+ 1351bd: e8 00 00 00 00 callq 0x1351c2 <thread-local initialization routine for data_type_for_v<seastar::basic_sstring<char, unsigned int, 15u, true>>+0xf2>
00000000001351be: R_X86_64_PLT32 __asan_report_store8-0x4
1351c2: 64 48 8b 04 25 00 00 00 00 movq %fs:0x0, %rax
1351cb: 48 8d b8 00 00 00 00 leaq (%rax), %rdi
00000000001351ce: R_X86_64_TPOFF32 db::schema_tables::the_merge_lock+0x40
- 1351d2: e8 00 00 00 00 callq 0x1351d7 <__tls_init+0x107>
+ 1351d2: e8 00 00 00 00 callq 0x1351d7 <thread-local initialization routine for data_type_for_v<seastar::basic_sstring<char, unsigned int, 15u, true>>+0x107>
00000000001351d3: R_X86_64_PLT32 __asan_report_store8-0x4
1351d7: 64 48 8b 04 25 00 00 00 00 movq %fs:0x0, %rax
1351e0: 48 8d b8 00 00 00 00 leaq (%rax), %rdi
00000000001351e3: R_X86_64_TPOFF32 db::schema_tables::the_merge_lock+0x48
- 1351e7: e8 00 00 00 00 callq 0x1351ec <__tls_init+0x11c>
+ 1351e7: e8 00 00 00 00 callq 0x1351ec <thread-local initialization routine for data_type_for_v<seastar::basic_sstring<char, unsigned int, 15u, true>>+0x11c>
00000000001351e8: R_X86_64_PLT32 __asan_report_store8-0x4
1351ec: 0f 1f 40 00 nopl (%rax)
@@ -763956,7 +763957,7 @@
0000000000000000 <thread-local wrapper routine for data_type_for_v<seastar::basic_sstring<char, unsigned int, 15u, true>>>:
0: 50 pushq %rax
1: e8 00 00 00 00 callq 0x6 <thread-local wrapper routine for data_type_for_v<seastar::basic_sstring<char, unsigned int, 15u, true>>+0x6>
- 0000000000000002: R_X86_64_PLT32 .text+0x1350cc
+ 0000000000000002: R_X86_64_PLT32 thread-local initialization routine for data_type_for_v<seastar::basic_sstring<char, unsigned int, 15u, true>>-0x4
6: 64 48 8b 04 25 00 00 00 00 movq %fs:0x0, %rax
000000000000000b: R_X86_64_TPOFF32 data_type_for_v<seastar::basic_sstring<char, unsigned int, 15u, true>>
f: 59 popq %rcx
@@ -763967,7 +763968,7 @@
0000000000000000 <thread-local wrapper routine for data_type_for_v<int>>:
0: 50 pushq %rax
1: e8 00 00 00 00 callq 0x6 <thread-local wrapper routine for data_type_for_v<int>+0x6>
- 0000000000000002: R_X86_64_PLT32 .text+0x1350cc
+ 0000000000000002: R_X86_64_PLT32 thread-local initialization routine for data_type_for_v<seastar::basic_sstring<char, unsigned int, 15u, true>>-0x4
6: 64 48 8b 04 25 00 00 00 00 movq %fs:0x0, %rax
000000000000000b: R_X86_64_TPOFF32 data_type_for_v<int>
f: 59 popq %rcx |
My explanation: the patch changed a local symbol |
Is there a way to disable the pass as a workaround? I tried -mllvm -disablepass=globalopt, but it didn't work. |
AFAIK, there is no way to disable arbitrary passes. |
Thank you for your analysis. I will continue to look into this issue tonight. |
Thanks! |
Agreed, I believe this is key to the issue. This is a minimal reproducer: https://llvm.godbolt.org/z/n5berxjfo. @f2 = linkonce_odr hidden alias void (), ptr @f1
define void @foo() {
call void @f1()
ret void
}
define void @bar() {
call void @f2()
ret void
}
define internal void @f1() {
ret void
} IIUC, both LLVM 16 and LLVM 17 miscompiled. I expect that the call to I've created a draft PR #91483, but I still need some time to confirm this PR. Feel free giving it a try to see if everything is working as expected. :) |
The original reproducer now generates the call to __tls_init. I'll test the executable later. |
The executable also works. |
/cherry-pick c796900 |
…lvm#91483) Fixes llvm#91312. Don't perform the transform if the alias may be replaced at link time. (cherry picked from commit c796900)
/pull-request #92468 |
#92468 should be safe, but I have a question about suppressing the optimization for linkonce_odr/weak_odr, so I want to compile this example myself. However, trunk clang currently crashes
|
…lvm#91483) Fixes llvm#91312. Don't perform the transform if the alias may be replaced at link time. (cherry picked from commit c796900)
Thanks a lot for the fix and backport. |
Prior to 533b7c1, compiling some coroutine that references a TLS variable generates this wrapper:
It correctly calls
__tls_init
.With 533b7c1 and later, up to 18.1.1, the following TLS wrapper is generated:
The call to
__tls_init
was replaced by a call to some random function. When the coroutine is then called, it does not initialize the object.I will follow up with a full reproducer.
The text was updated successfully, but these errors were encountered: