-
Notifications
You must be signed in to change notification settings - Fork 13.1k
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
miscompiled TLS wrapper, likely coroutine related, with sanitizer #91312
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: