Commit 7c95e4b
[debugger] skip suspend for unattached threads (#18111)
When the debugger tries to suspend all the VM threads, it can happen with cooperative-suspend that it tries to suspend a thread that has previously been attached, but then did a "light" detach (that only unsets the domain). With the domain set to `NULL`, looking up a JitInfo for a given `ip` will result into a crash, but it isn't even necessarily needed for the purpose of suspending a thread.
More details: Consider the following:
```
(lldb) c
error: Process is running. Use 'process interrupt' to pause execution.
Process 12832 stopped
* thread #9, name = 'tid_a31f', queue = 'NSOperationQueue 0x8069b670 (QOS: UTILITY)', stop reason = breakpoint 1.1
frame #0: 0x00222870 WatchWCSessionAppWatchOSExtension`debugger_interrupt_critical(info=0x81365400, user_data=0xb04dc718) at debugger-agent.c:2716:6
2713 MonoDomain *domain = (MonoDomain *) mono_thread_info_get_suspend_state (info)->unwind_data [MONO_UNWIND_DATA_DOMAIN];
2714 if (!domain) {
2715 /* not attached */
-> 2716 ji = NULL;
2717 } else {
2718 ji = mono_jit_info_table_find_internal ( domain, MONO_CONTEXT_GET_IP (&mono_thread_info_get_suspend_state (info)->ctx), TRUE, TRUE);
2719 }
Target 0: (WatchWCSessionAppWatchOSExtension) stopped.
(lldb) bt
* thread #9, name = 'tid_a31f', queue = 'NSOperationQueue 0x8069b670 (QOS: UTILITY)', stop reason = breakpoint 1.1
* frame #0: 0x00222870 WatchWCSessionAppWatchOSExtension`debugger_interrupt_critical(info=0x81365400, user_data=0xb04dc718) at debugger-agent.c:2716:6
frame #1: 0x004e177b WatchWCSessionAppWatchOSExtension`mono_thread_info_safe_suspend_and_run(id=0xb0767000, interrupt_kernel=0, callback=(WatchWCSessionAppWatchOSExtension`debugger_interrupt_critical at debugger-agent.c:2708), user_data=0xb04dc718) at mono-threads.c:1358:19
frame #2: 0x00222799 WatchWCSessionAppWatchOSExtension`notify_thread(key=0x03994508, value=0x81378c00, user_data=0x00000000) at debugger-agent.c:2747:2
frame #3: 0x00355bd8 WatchWCSessionAppWatchOSExtension`mono_g_hash_table_foreach(hash=0x8007b4e0, func=(WatchWCSessionAppWatchOSExtension`notify_thread at debugger-agent.c:2733), user_data=0x00000000) at mono-hash.c:310:4
frame #4: 0x0021e955 WatchWCSessionAppWatchOSExtension`suspend_vm at debugger-agent.c:2844:3
frame #5: 0x00225ff0 WatchWCSessionAppWatchOSExtension`process_event(event=EVENT_KIND_THREAD_START, arg=0x039945d0, il_offset=0, ctx=0x00000000, events=0x805b28e0, suspend_policy=2) at debugger-agent.c:4012:3
frame #6: 0x00227c7c WatchWCSessionAppWatchOSExtension`process_profiler_event(event=EVENT_KIND_THREAD_START, arg=0x039945d0) at debugger-agent.c:4072:2
frame #7: 0x0021b174 WatchWCSessionAppWatchOSExtension`thread_startup(prof=0x00000000, tid=2957889536) at debugger-agent.c:4149:2
frame #8: 0x0037912d WatchWCSessionAppWatchOSExtension`mono_profiler_raise_thread_started(tid=2957889536) at profiler-events.h:103:1
frame #9: 0x003d53da WatchWCSessionAppWatchOSExtension`fire_attach_profiler_events(tid=0xb04dd000) at threads.c:1120:2
frame #10: 0x003d4d83 WatchWCSessionAppWatchOSExtension`mono_thread_attach(domain=0x801750a0) at threads.c:1547:2
frame #11: 0x003df1a1 WatchWCSessionAppWatchOSExtension`mono_threads_attach_coop_internal(domain=0x801750a0, cookie=0xb04dcc0c, stackdata=0xb04dcba8) at threads.c:6008:3
frame #12: 0x003df287 WatchWCSessionAppWatchOSExtension`mono_threads_attach_coop(domain=0x00000000, dummy=0xb04dcc0c) at threads.c:6045:9
frame #13: 0x005034b8 WatchWCSessionAppWatchOSExtension`::xamarin_switch_gchandle(self=0x80762c20, to_weak=false) at runtime.m:1805:2
frame #14: 0x005065c1 WatchWCSessionAppWatchOSExtension`::xamarin_retain_trampoline(self=0x80762c20, sel="retain") at trampolines.m:693:2
frame #15: 0x657ea520 libobjc.A.dylib`objc_retain + 64
frame #16: 0x4b4d9caa WatchConnectivity`__66-[WCSession onqueue_handleDictionaryMessageRequest:withPairingID:]_block_invoke + 279
frame #17: 0x453c7df7 Foundation`__NSBLOCKOPERATION_IS_CALLING_OUT_TO_A_BLOCK__ + 12
frame #18: 0x453c7cf4 Foundation`-[NSBlockOperation main] + 88
frame #19: 0x453cacee Foundation`__NSOPERATION_IS_INVOKING_MAIN__ + 27
frame #20: 0x453c6ebd Foundation`-[NSOperation start] + 835
frame #21: 0x453cb606 Foundation`__NSOPERATIONQUEUE_IS_STARTING_AN_OPERATION__ + 27
frame #22: 0x453cb12e Foundation`__NSOQSchedule_f + 194
frame #23: 0x453cb26e Foundation`____addOperations_block_invoke_4 + 20
frame #24: 0x65de007b libdispatch.dylib`_dispatch_call_block_and_release + 15
frame #25: 0x65de126f libdispatch.dylib`_dispatch_client_callout + 14
frame #26: 0x65de3788 libdispatch.dylib`_dispatch_continuation_pop + 421
frame #27: 0x65de2ee3 libdispatch.dylib`_dispatch_async_redirect_invoke + 818
frame #28: 0x65df087d libdispatch.dylib`_dispatch_root_queue_drain + 354
frame #29: 0x65df0ff3 libdispatch.dylib`_dispatch_worker_thread2 + 109
frame #30: 0x66024fa0 libsystem_pthread.dylib`_pthread_wqthread + 208
frame #31: 0x66024e44 libsystem_pthread.dylib`start_wqthread + 36
```
Going further, `info` is about this thread:
```
(lldb) p/x *(int *)(((char *) info->node.key) + 0xa0)
(int) $2 = 0x01243f93
(lldb) thread list
Process 12832 stopped
thread #1: tid = 0x1243ee1, 0x65f7e396 libsystem_kernel.dylib`mach_msg_trap + 10, name = 'tid_303', queue = 'com.apple.main-thread'
thread #2: tid = 0x1243ee6, 0x65f816e2 libsystem_kernel.dylib`__recvfrom + 10
thread #3: tid = 0x1243ee7, 0x65f81aea libsystem_kernel.dylib`__psynch_cvwait + 10, name = 'SGen worker'
thread #4: tid = 0x1243ee9, 0x65f7e3d2 libsystem_kernel.dylib`semaphore_wait_trap + 10, name = 'Finalizer'
thread #5: tid = 0x1243eea, 0x65f816e2 libsystem_kernel.dylib`__recvfrom + 10, name = 'Debugger agent'
thread #6: tid = 0x1243f1d, 0x65f7e396 libsystem_kernel.dylib`mach_msg_trap + 10, name = 'com.apple.uikit.eventfetch-thread'
thread #8: tid = 0x1243f93, 0x65f7e396 libsystem_kernel.dylib`mach_msg_trap + 10, name = 'tid_6d0f', queue = 'NSOperationQueue 0x8069b300 (QOS: UTILITY)'
* thread #9: tid = 0x12443a9, 0x00222870 WatchWCSessionAppWatchOSExtension`debugger_interrupt_critical(info=0x81365400, user_data=0xb04dc718) at debugger-agent.c:2716:6, name = 'tid_a31f', queue = 'NSOperationQueue 0x8069b670 (QOS: UTILITY)', stop reason = breakpoint 1.1
thread #10: tid = 0x1244581, 0x65f7fd32 libsystem_kernel.dylib`__workq_kernreturn + 10
(lldb) thread select 8
* thread #8, name = 'tid_6d0f', queue = 'NSOperationQueue 0x8069b300 (QOS: UTILITY)'
frame #0: 0x65f7e396 libsystem_kernel.dylib`mach_msg_trap + 10
libsystem_kernel.dylib`mach_msg_trap:
-> 0x65f7e396 <+10>: retl
0x65f7e397 <+11>: nop
libsystem_kernel.dylib`mach_msg_overwrite_trap:
0x65f7e398 <+0>: movl $0xffffffe0, %eax ; imm = 0xFFFFFFE0
0x65f7e39d <+5>: calll 0x65f85f44 ; _sysenter_trap
(lldb) bt
* thread #8, name = 'tid_6d0f', queue = 'NSOperationQueue 0x8069b300 (QOS: UTILITY)'
* frame #0: 0x65f7e396 libsystem_kernel.dylib`mach_msg_trap + 10
frame #1: 0x65f7e8ff libsystem_kernel.dylib`mach_msg + 47
frame #2: 0x66079679 libxpc.dylib`_xpc_send_serializer + 104
frame #3: 0x660794da libxpc.dylib`_xpc_pipe_simpleroutine + 80
frame #4: 0x66079852 libxpc.dylib`xpc_pipe_simpleroutine + 43
frame #5: 0x66043a8f libsystem_trace.dylib`___os_activity_stream_reflect_block_invoke_2 + 30
frame #6: 0x65de126f libdispatch.dylib`_dispatch_client_callout + 14
frame #7: 0x65de3d71 libdispatch.dylib`_dispatch_block_invoke_direct + 257
frame #8: 0x65de3c62 libdispatch.dylib`dispatch_block_perform + 112
frame #9: 0x6604349a libsystem_trace.dylib`_os_activity_stream_reflect + 725
frame #10: 0x6604ef19 libsystem_trace.dylib`_os_log_impl_stream + 468
frame #11: 0x6604e44d libsystem_trace.dylib`_os_log_impl_flatten_and_send + 6410
frame #12: 0x6604cb3b libsystem_trace.dylib`_os_log + 137
frame #13: 0x6604f4aa libsystem_trace.dylib`_os_log_impl + 31
frame #14: 0x4b4eb4e9 WatchConnectivity`WCSerializePayloadDictionary + 393
frame #15: 0x4b4d7c4d WatchConnectivity`-[WCSession onqueue_sendResponseDictionary:identifier:] + 195
frame #16: 0x4b4da435 WatchConnectivity`__66-[WCSession onqueue_handleDictionaryMessageRequest:withPairingID:]_block_invoke.411 + 35
frame #17: 0x453c7df7 Foundation`__NSBLOCKOPERATION_IS_CALLING_OUT_TO_A_BLOCK__ + 12
frame #18: 0x453c7cf4 Foundation`-[NSBlockOperation main] + 88
frame #19: 0x453cacee Foundation`__NSOPERATION_IS_INVOKING_MAIN__ + 27
frame #20: 0x453c6ebd Foundation`-[NSOperation start] + 835
frame #21: 0x453cb606 Foundation`__NSOPERATIONQUEUE_IS_STARTING_AN_OPERATION__ + 27
frame #22: 0x453cb12e Foundation`__NSOQSchedule_f + 194
frame #23: 0x453cb067 Foundation`____addOperations_block_invoke_2 + 20
frame #24: 0x65dedf49 libdispatch.dylib`_dispatch_block_async_invoke2 + 77
frame #25: 0x65de4461 libdispatch.dylib`_dispatch_block_async_invoke_and_release + 17
frame #26: 0x65de126f libdispatch.dylib`_dispatch_client_callout + 14
frame #27: 0x65de3788 libdispatch.dylib`_dispatch_continuation_pop + 421
frame #28: 0x65de2ee3 libdispatch.dylib`_dispatch_async_redirect_invoke + 818
frame #29: 0x65df087d libdispatch.dylib`_dispatch_root_queue_drain + 354
frame #30: 0x65df0ff3 libdispatch.dylib`_dispatch_worker_thread2 + 109
frame #31: 0x66024fa0 libsystem_pthread.dylib`_pthread_wqthread + 208
frame #32: 0x66024e44 libsystem_pthread.dylib`start_wqthread + 36
```
which is a thread in a "light" detach state (aka. coop detach), where we only unset the domain:
https://github.com/mono/mono/blob/4cefdcb7ce2d939ee78fb45d1b4913eb3bc064fd/mono/metadata/threads.c#L6084-L6111
Fixes #179261 parent 77147e7 commit 7c95e4b
1 file changed
+7
-5
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2717 | 2717 | | |
2718 | 2718 | | |
2719 | 2719 | | |
2720 | | - | |
2721 | | - | |
2722 | | - | |
2723 | | - | |
2724 | | - | |
| 2720 | + | |
| 2721 | + | |
| 2722 | + | |
| 2723 | + | |
| 2724 | + | |
| 2725 | + | |
| 2726 | + | |
2725 | 2727 | | |
2726 | 2728 | | |
2727 | 2729 | | |
| |||
0 commit comments