@@ -2453,137 +2453,6 @@ process_frame_chain(
24532453 return 0 ;
24542454}
24552455
2456- <<<<<<< Updated upstream
2457- == == == =
2458- static int
2459- get_thread_status (RemoteUnwinderObject * unwinder , uint64_t tid , uint64_t pthread_id ) {
2460- #if defined(__APPLE__ ) && TARGET_OS_OSX
2461- if (unwinder -> thread_id_offset == 0 ) {
2462- uint64_t * tids = (uint64_t * )PyMem_Malloc (MAX_NATIVE_THREADS * sizeof (uint64_t ));
2463- if (!tids ) {
2464- PyErr_NoMemory ();
2465- return -1 ;
2466- }
2467- int n = proc_pidinfo (unwinder -> handle .pid , PROC_PIDLISTTHREADS , 0 , tids , MAX_NATIVE_THREADS * sizeof (uint64_t )) / sizeof (uint64_t );
2468- if (n <= 0 ) {
2469- PyMem_Free (tids );
2470- return THREAD_STATE_UNKNOWN ;
2471- }
2472- uint64_t min_offset = UINT64_MAX ;
2473- for (int i = 0 ; i < n ; i ++ ) {
2474- uint64_t offset = tids [i ] - pthread_id ;
2475- if (offset < min_offset ) {
2476- min_offset = offset ;
2477- }
2478- }
2479- unwinder -> thread_id_offset = min_offset ;
2480- PyMem_Free (tids );
2481- }
2482- struct proc_threadinfo ti ;
2483- uint64_t tid_with_offset = pthread_id + unwinder -> thread_id_offset ;
2484- if (proc_pidinfo (unwinder -> handle .pid , PROC_PIDTHREADINFO , tid_with_offset , & ti , sizeof (ti )) != sizeof (ti )) {
2485- return THREAD_STATE_UNKNOWN ;
2486- }
2487- if (ti .pth_run_state == TH_STATE_RUNNING ) {
2488- return THREAD_STATE_RUNNING ;
2489- }
2490- return THREAD_STATE_IDLE ;
2491- #elif defined(__linux__ ) && HAVE_PROCESS_VM_READV
2492- char stat_path [256 ];
2493- char buffer [2048 ] = "" ;
2494-
2495- snprintf (stat_path , sizeof (stat_path ), "/proc/%d/task/%lu/stat" , unwinder -> handle .pid , tid );
2496-
2497- int fd = open (stat_path , O_RDONLY );
2498- if (fd == -1 ) {
2499- return THREAD_STATE_UNKNOWN ;
2500- }
2501-
2502- if (read (fd , buffer , 2047 ) == 0 ) {
2503- close (fd );
2504- return THREAD_STATE_UNKNOWN ;
2505- }
2506- close (fd );
2507-
2508- char * p = strchr (buffer , ')' );
2509- if (!p ) {
2510- return THREAD_STATE_UNKNOWN ;
2511- }
2512-
2513- p += 2 ; // Skip ") "
2514- if (* p == ' ' ) {
2515- p ++ ;
2516- }
2517-
2518- switch (* p ) {
2519- case 'R' : // Running
2520- return THREAD_STATE_RUNNING ;
2521- case 'S' : // Interruptible sleep
2522- case 'D' : // Uninterruptible sleep
2523- case 'T' : // Stopped
2524- case 'Z' : // Zombie
2525- case 'I' : // Idle kernel thread
2526- return THREAD_STATE_IDLE ;
2527- default :
2528- return THREAD_STATE_UNKNOWN ;
2529- }
2530- #elif defined(MS_WINDOWS )
2531- ULONG n ;
2532- NTSTATUS status = NtQuerySystemInformation (
2533- SystemProcessInformation ,
2534- unwinder -> win_process_buffer ,
2535- unwinder -> win_process_buffer_size ,
2536- & n
2537- );
2538- if (status == STATUS_INFO_LENGTH_MISMATCH ) {
2539- // Buffer was too small so we reallocate a larger one and try again.
2540- unwinder -> win_process_buffer_size = n ;
2541- PVOID new_buffer = PyMem_Realloc (unwinder -> win_process_buffer , n );
2542- if (!new_buffer ) {
2543- return -1 ;
2544- }
2545- unwinder -> win_process_buffer = new_buffer ;
2546- return get_thread_status (unwinder , tid , pthread_id );
2547- }
2548- if (status != STATUS_SUCCESS ) {
2549- return -1 ;
2550- }
2551-
2552- SYSTEM_PROCESS_INFORMATION * pi = (SYSTEM_PROCESS_INFORMATION * )unwinder -> win_process_buffer ;
2553- while ((ULONG )(ULONG_PTR )pi -> UniqueProcessId != unwinder -> handle .pid ) {
2554- if (pi -> NextEntryOffset == 0 ) {
2555- // We didn't find the process
2556- return -1 ;
2557- }
2558- pi = (SYSTEM_PROCESS_INFORMATION * )(((BYTE * )pi ) + pi -> NextEntryOffset );
2559- }
2560-
2561- SYSTEM_THREAD_INFORMATION * ti = (SYSTEM_THREAD_INFORMATION * )((char * )pi + sizeof (SYSTEM_PROCESS_INFORMATION ));
2562- for (Py_ssize_t i = 0 ; i < pi -> NumberOfThreads ; i ++ , ti ++ ) {
2563- if (ti -> ClientId .UniqueThread == (HANDLE )tid ) {
2564- return ti -> ThreadState != WIN32_THREADSTATE_RUNNING ? THREAD_STATE_IDLE : THREAD_STATE_RUNNING ;
2565- }
2566- }
2567-
2568- return -1 ;
2569- #else
2570- return THREAD_STATE_UNKNOWN ;
2571- #endif
2572- }
2573-
2574- typedef struct {
2575- unsigned int initialized :1 ;
2576- unsigned int bound :1 ;
2577- unsigned int unbound :1 ;
2578- unsigned int bound_gilstate :1 ;
2579- unsigned int active :1 ;
2580- unsigned int finalizing :1 ;
2581- unsigned int cleared :1 ;
2582- unsigned int finalized :1 ;
2583- unsigned int :24 ;
2584- } _thread_status ;
2585-
2586- >>>>>>> Stashed changes
25872456static PyObject *
25882457unwind_stack_for_thread (
25892458 RemoteUnwinderObject * unwinder ,
0 commit comments