@@ -716,7 +716,7 @@ find_running_task_in_thread(
716716}
717717
718718int
719- get_task_code_object (RemoteUnwinderObject * unwinder , uintptr_t task_addr , uintptr_t * code_obj_addr ) {
719+ get_task_frame (RemoteUnwinderObject * unwinder , uintptr_t task_addr , uintptr_t * frame_addr ) {
720720 uintptr_t running_coro_addr = 0 ;
721721
722722 if (read_py_ptr (
@@ -733,21 +733,7 @@ get_task_code_object(RemoteUnwinderObject *unwinder, uintptr_t task_addr, uintpt
733733 return -1 ;
734734 }
735735
736- // note: genobject's gi_iframe is an embedded struct so the address to
737- // the offset leads directly to its first field: f_executable
738- if (read_py_ptr (
739- unwinder ,
740- running_coro_addr + (uintptr_t )unwinder -> debug_offsets .gen_object .gi_iframe , code_obj_addr ) < 0 ) {
741- set_exception_cause (unwinder , PyExc_RuntimeError , "Failed to read running task code object" );
742- return -1 ;
743- }
744-
745- if (* code_obj_addr == 0 ) {
746- PyErr_SetString (PyExc_RuntimeError , "Running task code object is NULL" );
747- set_exception_cause (unwinder , PyExc_RuntimeError , "Running task code object address is NULL" );
748- return -1 ;
749- }
750-
736+ * frame_addr = running_coro_addr + (uintptr_t )unwinder -> debug_offsets .gen_object .gi_iframe ;
751737 return 0 ;
752738}
753739
@@ -760,7 +746,7 @@ parse_async_frame_chain(
760746 RemoteUnwinderObject * unwinder ,
761747 PyObject * calls ,
762748 uintptr_t address_of_thread ,
763- uintptr_t running_task_code_obj
749+ uintptr_t running_task_frame
764750) {
765751 uintptr_t address_of_current_frame ;
766752 if (find_running_frame (unwinder , address_of_thread , & address_of_current_frame ) < 0 ) {
@@ -777,6 +763,8 @@ parse_async_frame_chain(
777763 }
778764 PyObject * frame_info = NULL ;
779765 uintptr_t address_of_code_object ;
766+
767+ uintptr_t this_frame = address_of_current_frame ;
780768 int res = parse_frame_object (
781769 unwinder ,
782770 & frame_info ,
@@ -802,7 +790,9 @@ parse_async_frame_chain(
802790
803791 Py_DECREF (frame_info );
804792
805- if (address_of_code_object == running_task_code_obj ) {
793+ // Stop at the task's own frame. Code objects are shared by
794+ // recursive calls, so they cannot identify it.
795+ if (this_frame == running_task_frame ) {
806796 break ;
807797 }
808798 }
@@ -938,8 +928,8 @@ process_running_task_chain(
938928 uintptr_t thread_state_addr ,
939929 PyObject * result
940930) {
941- uintptr_t running_task_code_obj = 0 ;
942- if (get_task_code_object (unwinder , running_task_addr , & running_task_code_obj ) < 0 ) {
931+ uintptr_t running_task_frame = 0 ;
932+ if (get_task_frame (unwinder , running_task_addr , & running_task_frame ) < 0 ) {
943933 return -1 ;
944934 }
945935
@@ -971,7 +961,7 @@ process_running_task_chain(
971961 }
972962
973963 // Add the chain from the current frame to this task
974- if (parse_async_frame_chain (unwinder , frame_chain , thread_state_addr , running_task_code_obj ) < 0 ) {
964+ if (parse_async_frame_chain (unwinder , frame_chain , thread_state_addr , running_task_frame ) < 0 ) {
975965 return -1 ;
976966 }
977967
0 commit comments