Open4
WasmLinux: スレッドが正常に終了しない問題
pthreadで作成したスレッドから return
してもスレッドが消えてくれず、しかも何かスケジューラが狂う。
とりあえず do_task_dead
から戻ってしまっているっぽいので、その理由をstep実行で追う。
最後のswitch toで暴走が始まる
backtrace的には __switch_to
の sem_down
の箇所に居る。このまま thread_exit
まで走るのが期待値だが、downしたまま帰ってきていない。
... そもそも arch_free_task_stack
が呼ばれてないな。。
ユーザスレッドを実装するためには、この辺の実装の補完が必要っぽい。
(lldb) bt
* thread #29, name = 'runner'
* frame #0: 0x00007ffff7b2cb4d libc.so.6`syscall + 29
frame #1: 0x00000000026a6f8b runner`void std::__detail::__platform_wait<int>(__addr=0x00007ffd78000bc0, __val=0) at atomic_wait.h:112:21
frame #2: 0x00000000026a705c runner`void std::__atomic_wait_address_bare<std::__atomic_semaphore::_M_acquire()::'lambda'()>(__addr=0x00007ffd78000bc0, __pred=(unnamed struct) @ 0x00007ffd7fffe4e0) at atomic_wait.h:448:29
frame #3: 0x00000000026a73af runner`std::counting_semaphore<2147483647l>::acquire() [inlined] std::__atomic_semaphore::_M_acquire(this=0x00007ffd78000bc0) at semaphore_base.h:215:38
frame #4: 0x00000000026a7394 runner`std::counting_semaphore<2147483647l>::acquire(this=0x00007ffd78000bc0) at semaphore:74:26
frame #5: 0x00000000026a5230 runner`mod_syncobjects(in=0x00007ffe38e81c58, out=0x00007ffdf7a22000) at runner.cpp:606:41
frame #6: 0x00000000026a6824 runner`w2c_env_nccc_call64(env=0x0000000000000000, inptr=1095105616, outptr=0) at runner.cpp:1182:28
frame #7: 0x0000000001374889 runner`w2c_kernel_host_sem_down(instance=0x00007ffd74000b70, var_p0=62) at lin.c:1704678
frame #8: 0x000000000120065e runner`w2c_kernel_0x5F_switch_to(instance=0x00007ffd74000b70, var_p0=458636, var_p1=258) at lin.c:1560848
frame #9: 0x00000000010aec3e runner`w2c_kernel_0x5F_schedule(instance=0x00007ffd74000b70, var_p0=943677440) at lin.c:1427291
frame #10: 0x00000000010ad492 runner`w2c_kernel_do_task_dead(instance=0x00007ffd74000b70) at lin.c:1426837
frame #11: 0x0000000000f17dfc runner`w2c_kernel_do_exit(instance=0x00007ffd74000b70, var_p0=1095106264) at lin.c:1269310
frame #12: 0x0000000000f18e67 runner`w2c_kernel_do_group_exit(instance=0x00007ffd74000b70, var_p0=0) at lin.c:1269701
frame #13: 0x0000000000f18eb6 runner`w2c_kernel_0x5F_se_sys_exit_group(instance=0x00007ffd74000b70, var_p0=0) at lin.c:1269714
frame #14: 0x0000000001350988 runner`w2c_kernel_lkl_syscall(instance=0x00007ffd74000b70, var_p0=94, var_p1=1, var_p2=948842128) at lin.c:1692095
frame #15: 0x000000000137395c runner`w2c_kernel_syscall_0(instance=0x00007ffd74000b70, var_p0=94, var_p1=1, var_p2=948842128) at lin.c:1704248
frame #16: 0x0000000000403f37 runner`w2c_kernel_syscall(instance=0x00007ffd74000b70, var_p0=94, var_p1=1, var_p2=948842128) at lin.c:191103:10
frame #17: 0x00000000026a46db runner`runsyscall32(no=94, nargs=1, in=948842128) at runner.cpp:257:30
frame #18: 0x00000000026a4878 runner`w2c_env_wasmlinux_syscall32(env=0x0000000000000000, argc=1, no=94, args=948842128) at runner.cpp:330:24
frame #19: 0x0000000002684941 runner`w2c_user_0x5FExit(instance=0x00007ffd74000bc0, var_p0=0) at user.c:2868:12
frame #20: 0x0000000002684c24 runner`w2c_user_exit(instance=0x00007ffd74000bc0, var_p0=0) at user.c:2930:3
frame #21: 0x000000000269ea1f runner`w2c_user_0x5F_pthread_exit(instance=0x00007ffd74000bc0, var_p0=1059458288) at user.c:11878:3
frame #22: 0x00000000026a150a runner`w2c_user_start(instance=0x00007ffd74000bc0, var_p0=948842352) at user.c:12855:3
frame #23: 0x00000000026a4e8f runner`thr_uthr(args=0x0000000000000000) at runner.cpp:521:10
frame #24: 0x00000000026a95b6 runner`void std::__invoke_impl<void, void (*)(userthr_args*), userthr_args*>((null)=__invoke_other @ 0x00007ffd7fffeb10, __f=0x00007ffd78000d40, (null)=0x00007ffd78000d38) at invoke.h:61:36
frame #25: 0x00000000026a9303 runner`std::__invoke_result<void (*)(userthr_args*), userthr_args*>::type std::__invoke<void (*)(userthr_args*), userthr_args*>(__fn=0x00007ffd78000d40, (null)=0x00007ffd78000d38) at invoke.h:96:40
frame #26: 0x00000000026a903d runner`void std::thread::_Invoker<std::tuple<void (*)(userthr_args*), userthr_args*>>::_M_invoke<0ul, 1ul>(this=0x00007ffd78000d38, (null)=_Index_tuple<0, 1> @ 0x00007ffd7fffeb70) at std_thread.h:292:26
frame #27: 0x00000000026a8edc runner`std::thread::_Invoker<std::tuple<void (*)(userthr_args*), userthr_args*>>::operator()(this=0x00007ffd78000d38) at std_thread.h:299:20
frame #28: 0x00000000026a8e4e runner`std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)(userthr_args*), userthr_args*>>>::_M_run(this=0x00007ffd78000d30) at std_thread.h:244:20
frame #29: 0x00007ffff7ce31b3 libstdc++.so.6`execute_native_thread_routine + 19
frame #30: 0x00007ffff7aae947 libc.so.6`start_thread + 759
frame #31: 0x00007ffff7b34860 libc.so.6`__clone3 + 48
そもそも、 sys_exit_group
なのも間違ってるな。。libcがスレッド対応になっていないっぽい。
__switch_to
で処理することに
とりあえず
とりあえずコレで終了はするようになった。 ...終了は。。
clone
のvararg処理ミスだった
急にexitしてくるのは このミスによりTLSが設定されない → pthread_self()
が誤動作する → 自分が最後のスレッドだと勘違いして exit
する のコンボが決まっていた。
... CLEARの方を見ないとダメだったね。。
ここまでで、 pthread_create
〜 pthread_exit
〜 pthread_join
まで確認できたので、とりあえずスレッドの基本的な挙動は実現できていると思う。さぁシグナルだ。。