| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 0319992 commit e92ca41
1 file changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -39,6 +39,8 @@ | |||
| 39 | 39 | * ============================================================================ */ | |
| 40 | 40 | ||
| 41 | 41 | #define GET_MEMBER(type, obj, offset) (*(type*)((char*)(obj) + (offset))) | |
| 42 | + #define CLEAR_PTR_TAG(ptr) (((uintptr_t)(ptr) & ~Py_TAG_BITS)) | ||
| 43 | + #define GET_MEMBER_NO_TAG(type, obj, offset) (type)(CLEAR_PTR_TAG(*(type*)((char*)(obj) + (offset)))) | ||
| 42 | 44 | ||
| 43 | 45 | /* Size macros for opaque buffers */ | |
| 44 | 46 | #define SIZEOF_BYTES_OBJ sizeof(PyBytesObject) | |
@@ -243,6 +245,13 @@ module _remote_debugging | |||
| 243 | 245 | * FORWARD DECLARATIONS | |
| 244 | 246 | * ============================================================================ */ | |
| 245 | 247 | ||
| 248 | + static inline int | ||
| 249 | + is_frame_valid( | ||
| 250 | + RemoteUnwinderObject *unwinder, | ||
| 251 | + uintptr_t frame_addr, | ||
| 252 | + uintptr_t code_object_addr | ||
| 253 | + ); | ||
| 254 | + | ||
| 246 | 255 | static int | |
| 247 | 256 | parse_tasks_in_set( | |
| 248 | 257 | RemoteUnwinderObject *unwinder, | |
@@ -734,8 +743,7 @@ parse_task_name( | |||
| 734 | 743 | return NULL; | |
| 735 | 744 | } | |
| 736 | 745 | ||
| 737 | - uintptr_t task_name_addr = GET_MEMBER(uintptr_t, task_obj, unwinder->async_debug_offsets.asyncio_task_object.task_name); | ||
| 738 | - task_name_addr &= ~Py_TAG_BITS; | ||
| 746 | + uintptr_t task_name_addr = GET_MEMBER_NO_TAG(uintptr_t, task_obj, unwinder->async_debug_offsets.asyncio_task_object.task_name); | ||
| 739 | 747 | ||
| 740 | 748 | // The task name can be a long or a string so we need to check the type | |
| 741 | 749 | char task_name_obj[SIZEOF_PYOBJECT]; | |
@@ -798,8 +806,7 @@ static int parse_task_awaited_by( | |||
| 798 | 806 | return -1; | |
| 799 | 807 | } | |
| 800 | 808 | ||
| 801 | - uintptr_t task_ab_addr = GET_MEMBER(uintptr_t, task_obj, unwinder->async_debug_offsets.asyncio_task_object.task_awaited_by); | ||
| 802 | - task_ab_addr &= ~Py_TAG_BITS; | ||
| 809 | + uintptr_t task_ab_addr = GET_MEMBER_NO_TAG(uintptr_t, task_obj, unwinder->async_debug_offsets.asyncio_task_object.task_awaited_by); | ||
| 803 | 810 | ||
| 804 | 811 | if ((void*)task_ab_addr == NULL) { | |
| 805 | 812 | return 0; | |
@@ -849,8 +856,7 @@ handle_yield_from_frame( | |||
| 849 | 856 | return -1; | |
| 850 | 857 | } | |
| 851 | 858 | ||
| 852 | - uintptr_t stackpointer_addr = GET_MEMBER(uintptr_t, iframe, unwinder->debug_offsets.interpreter_frame.stackpointer); | ||
| 853 | - stackpointer_addr &= ~Py_TAG_BITS; | ||
| 859 | + uintptr_t stackpointer_addr = GET_MEMBER_NO_TAG(uintptr_t, iframe, unwinder->debug_offsets.interpreter_frame.stackpointer); | ||
| 854 | 860 | ||
| 855 | 861 | if ((void*)stackpointer_addr != NULL) { | |
| 856 | 862 | uintptr_t gi_await_addr; | |
@@ -917,6 +923,11 @@ parse_coro_chain( | |||
| 917 | 923 | return -1; | |
| 918 | 924 | } | |
| 919 | 925 | ||
| 926 | + int8_t frame_state = GET_MEMBER(int8_t, gen_object, unwinder->debug_offsets.gen_object.gi_frame_state); | ||
| 927 | + if (frame_state == FRAME_CLEARED) { | ||
| 928 | + return 0; | ||
| 929 | + } | ||
| 930 | + | ||
| 920 | 931 | uintptr_t gen_type_addr = GET_MEMBER(uintptr_t, gen_object, unwinder->debug_offsets.pyobject.ob_type); | |
| 921 | 932 | ||
| 922 | 933 | PyObject* name = NULL; | |
@@ -936,7 +947,7 @@ parse_coro_chain( | |||
| 936 | 947 | } | |
| 937 | 948 | Py_DECREF(name); | |
| 938 | 949 | ||
| 939 | - if (GET_MEMBER(int8_t, gen_object, unwinder->debug_offsets.gen_object.gi_frame_state) == FRAME_SUSPENDED_YIELD_FROM) { | ||
| 950 | + if (frame_state == FRAME_SUSPENDED_YIELD_FROM) { | ||
| 940 | 951 | return handle_yield_from_frame(unwinder, gi_iframe_addr, gen_type_addr, render_to); | |
| 941 | 952 | } | |
| 942 | 953 | ||
@@ -981,8 +992,7 @@ create_task_result( | |||
| 981 | 992 | goto error; | |
| 982 | 993 | } | |
| 983 | 994 | ||
| 984 | - coro_addr = GET_MEMBER(uintptr_t, task_obj, unwinder->async_debug_offsets.asyncio_task_object.task_coro); | ||
| 985 | - coro_addr &= ~Py_TAG_BITS; | ||
| 995 | + coro_addr = GET_MEMBER_NO_TAG(uintptr_t, task_obj, unwinder->async_debug_offsets.asyncio_task_object.task_coro); | ||
| 986 | 996 | ||
| 987 | 997 | if ((void*)coro_addr != NULL) { | |
| 988 | 998 | if (parse_coro_chain(unwinder, coro_addr, call_stack) < 0) { | |
@@ -1816,10 +1826,10 @@ parse_frame_from_chunks( | |||
| 1816 | 1826 | ||
| 1817 | 1827 | char *frame = (char *)frame_ptr; | |
| 1818 | 1828 | *previous_frame = GET_MEMBER(uintptr_t, frame, unwinder->debug_offsets.interpreter_frame.previous); | |
| 1819 | - | ||
| 1820 | - if (GET_MEMBER(char, frame, unwinder->debug_offsets.interpreter_frame.owner) >= FRAME_OWNED_BY_INTERPRETER || | ||
| 1821 | - !GET_MEMBER(uintptr_t, frame, unwinder->debug_offsets.interpreter_frame.executable)) { | ||
| 1822 | - return 0; | ||
| 1829 | + uintptr_t code_object = GET_MEMBER_NO_TAG(uintptr_t, frame_ptr, unwinder->debug_offsets.interpreter_frame.executable); | ||
| 1830 | + int frame_valid = is_frame_valid(unwinder, (uintptr_t)frame, code_object); | ||
| 1831 | + if (frame_valid != 1) { | ||
| 1832 | + return frame_valid; | ||
| 1823 | 1833 | } | |
| 1824 | 1834 | ||
| 1825 | 1835 | uintptr_t instruction_pointer = GET_MEMBER(uintptr_t, frame, unwinder->debug_offsets.interpreter_frame.instr_ptr); | |
@@ -1832,9 +1842,7 @@ parse_frame_from_chunks( | |||
| 1832 | 1842 | } | |
| 1833 | 1843 | #endif | |
| 1834 | 1844 | ||
| 1835 | - return parse_code_object( | ||
| 1836 | - unwinder, result, GET_MEMBER(uintptr_t, frame, unwinder->debug_offsets.interpreter_frame.executable), | ||
| 1837 | - instruction_pointer, previous_frame, tlbc_index); | ||
| 1845 | + return parse_code_object(unwinder, result, code_object, instruction_pointer, previous_frame, tlbc_index); | ||
| 1838 | 1846 | } | |
| 1839 | 1847 | ||
| 1840 | 1848 | /* ============================================================================ | |
@@ -2077,6 +2085,33 @@ find_running_task_and_coro( | |||
| 2077 | 2085 | * FRAME PARSING FUNCTIONS | |
| 2078 | 2086 | * ============================================================================ */ | |
| 2079 | 2087 | ||
| 2088 | + static inline int | ||
| 2089 | + is_frame_valid( | ||
| 2090 | + RemoteUnwinderObject *unwinder, | ||
| 2091 | + uintptr_t frame_addr, | ||
| 2092 | + uintptr_t code_object_addr | ||
| 2093 | + ) { | ||
| 2094 | + if ((void*)code_object_addr == NULL) { | ||
| 2095 | + return 0; | ||
| 2096 | + } | ||
| 2097 | + | ||
| 2098 | + void* frame = (void*)frame_addr; | ||
| 2099 | + | ||
| 2100 | + if (GET_MEMBER(char, frame, unwinder->debug_offsets.interpreter_frame.owner) == FRAME_OWNED_BY_CSTACK || | ||
| 2101 | + GET_MEMBER(char, frame, unwinder->debug_offsets.interpreter_frame.owner) == FRAME_OWNED_BY_INTERPRETER) { | ||
| 2102 | + return 0; // C frame | ||
| 2103 | + } | ||
| 2104 | + | ||
| 2105 | + if (GET_MEMBER(char, frame, unwinder->debug_offsets.interpreter_frame.owner) != FRAME_OWNED_BY_GENERATOR | ||
| 2106 | + && GET_MEMBER(char, frame, unwinder->debug_offsets.interpreter_frame.owner) != FRAME_OWNED_BY_THREAD) { | ||
| 2107 | + PyErr_Format(PyExc_RuntimeError, "Unhandled frame owner %d.\n", | ||
| 2108 | + GET_MEMBER(char, frame, unwinder->debug_offsets.interpreter_frame.owner)); | ||
| 2109 | + set_exception_cause(unwinder, PyExc_RuntimeError, "Unhandled frame owner type in async frame"); | ||
| 2110 | + return -1; | ||
| 2111 | + } | ||
| 2112 | + return 1; | ||
| 2113 | + } | ||
| 2114 | + | ||
| 2080 | 2115 | static int | |
| 2081 | 2116 | parse_frame_object( | |
| 2082 | 2117 | RemoteUnwinderObject *unwinder, | |
@@ -2098,13 +2133,10 @@ parse_frame_object( | |||
| 2098 | 2133 | } | |
| 2099 | 2134 | ||
| 2100 | 2135 | *previous_frame = GET_MEMBER(uintptr_t, frame, unwinder->debug_offsets.interpreter_frame.previous); | |
| 2101 | - | ||
| 2102 | - if (GET_MEMBER(char, frame, unwinder->debug_offsets.interpreter_frame.owner) >= FRAME_OWNED_BY_INTERPRETER) { | ||
| 2103 | - return 0; | ||
| 2104 | - } | ||
| 2105 | - | ||
| 2106 | - if ((void*)GET_MEMBER(uintptr_t, frame, unwinder->debug_offsets.interpreter_frame.executable) == NULL) { | ||
| 2107 | - return 0; | ||
| 2136 | + uintptr_t code_object = GET_MEMBER_NO_TAG(uintptr_t, frame, unwinder->debug_offsets.interpreter_frame.executable); | ||
| 2137 | + int frame_valid = is_frame_valid(unwinder, (uintptr_t)frame, code_object); | ||
| 2138 | + if (frame_valid != 1) { | ||
| 2139 | + return frame_valid; | ||
| 2108 | 2140 | } | |
| 2109 | 2141 | ||
| 2110 | 2142 | uintptr_t instruction_pointer = GET_MEMBER(uintptr_t, frame, unwinder->debug_offsets.interpreter_frame.instr_ptr); | |
@@ -2117,9 +2149,7 @@ parse_frame_object( | |||
| 2117 | 2149 | } | |
| 2118 | 2150 | #endif | |
| 2119 | 2151 | ||
| 2120 | - return parse_code_object( | ||
| 2121 | - unwinder, result, GET_MEMBER(uintptr_t, frame, unwinder->debug_offsets.interpreter_frame.executable), | ||
| 2122 | - instruction_pointer, previous_frame, tlbc_index); | ||
| 2152 | + return parse_code_object(unwinder, result, code_object,instruction_pointer, previous_frame, tlbc_index); | ||
| 2123 | 2153 | } | |
| 2124 | 2154 | ||
| 2125 | 2155 | static int | |
@@ -2144,26 +2174,10 @@ parse_async_frame_object( | |||
| 2144 | 2174 | } | |
| 2145 | 2175 | ||
| 2146 | 2176 | *previous_frame = GET_MEMBER(uintptr_t, frame, unwinder->debug_offsets.interpreter_frame.previous); | |
| 2147 | - | ||
| 2148 | - *code_object = GET_MEMBER(uintptr_t, frame, unwinder->debug_offsets.interpreter_frame.executable); | ||
| 2149 | - // Strip tag bits for consistent comparison | ||
| 2150 | - *code_object &= ~Py_TAG_BITS; | ||
| 2151 | - assert(code_object != NULL); | ||
| 2152 | - if ((void*)*code_object == NULL) { | ||
| 2153 | - return 0; | ||
| 2154 | - } | ||
| 2155 | - | ||
| 2156 | - if (GET_MEMBER(char, frame, unwinder->debug_offsets.interpreter_frame.owner) == FRAME_OWNED_BY_CSTACK || | ||
| 2157 | - GET_MEMBER(char, frame, unwinder->debug_offsets.interpreter_frame.owner) == FRAME_OWNED_BY_INTERPRETER) { | ||
| 2158 | - return 0; // C frame | ||
| 2159 | - } | ||
| 2160 | - | ||
| 2161 | - if (GET_MEMBER(char, frame, unwinder->debug_offsets.interpreter_frame.owner) != FRAME_OWNED_BY_GENERATOR | ||
| 2162 | - && GET_MEMBER(char, frame, unwinder->debug_offsets.interpreter_frame.owner) != FRAME_OWNED_BY_THREAD) { | ||
| 2163 | - PyErr_Format(PyExc_RuntimeError, "Unhandled frame owner %d.\n", | ||
| 2164 | - GET_MEMBER(char, frame, unwinder->debug_offsets.interpreter_frame.owner)); | ||
| 2165 | - set_exception_cause(unwinder, PyExc_RuntimeError, "Unhandled frame owner type in async frame"); | ||
| 2166 | - return -1; | ||
| 2177 | + *code_object = GET_MEMBER_NO_TAG(uintptr_t, frame, unwinder->debug_offsets.interpreter_frame.executable); | ||
| 2178 | + int frame_valid = is_frame_valid(unwinder, (uintptr_t)frame, *code_object); | ||
| 2179 | + if (frame_valid != 1) { | ||
| 2180 | + return frame_valid; | ||
| 2167 | 2181 | } | |
| 2168 | 2182 | ||
| 2169 | 2183 | uintptr_t instruction_pointer = GET_MEMBER(uintptr_t, frame, unwinder->debug_offsets.interpreter_frame.instr_ptr); | |
| Back | FazBrowse Home | New Git URL |
0 commit comments