Pewarta Proxy

📋 Server Request & Proxy Logs

Loading active proxy settings...
Developed by Khairul Adha (adhexa.id)
Mengambil log server...

⚙️ Pengaturan Proxy Target

Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
14 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Revert "[3.15] gh-158522: Fix truncated stack for a task whose corout…
…ine recurses (GH-158526) (#158870)"

This reverts commit a904b39.
  • Loading branch information
pablogsal committed Oct 5, 2026
commit b3cfee3fe54ea4e7f3babca719448c5673f53f01
16 changes: 0 additions & 16 deletions Lib/test/test_external_inspection.py
Original file line number Diff line number Diff line change
Expand Up @@ -492,22 +492,6 @@ async def main():
self.assertIn(main_name, names)
self.assertEqual([len(n) for n in names if n.startswith("x")], [255])

@skip_if_not_supported
def test_recursive_coroutine_stack_is_not_truncated(self):
# gh-158522
async def rec(n):
if n:
return await rec(n - 1)
return [
frame.funcname.rpartition(".")[2]
for task in RemoteUnwinder(
os.getpid()).get_async_stack_trace()[0].awaited_by
for coro in task.coroutine_stack
for frame in coro.call_stack
]

self.assertEqual(asyncio.run(rec(3)), ["rec"] * 4)

@skip_if_not_supported
@unittest.skipIf(
sys.platform == "linux" and not PROCESS_VM_READV_SUPPORTED,
Expand Down

This file was deleted.

6 changes: 3 additions & 3 deletions Modules/_remote_debugging/_remote_debugging.h
Original file line number Diff line number Diff line change
Expand Up @@ -729,7 +729,7 @@ extern int parse_async_frame_chain(
RemoteUnwinderObject *unwinder,
PyObject *calls,
uintptr_t address_of_thread,
uintptr_t running_task_frame
uintptr_t running_task_code_obj
);

extern int process_single_task_node(
Expand All @@ -745,10 +745,10 @@ extern int find_running_task_in_thread(
uintptr_t *running_task_addr
);

extern int get_task_frame(
extern int get_task_code_object(
RemoteUnwinderObject *unwinder,
uintptr_t task_addr,
uintptr_t *frame_addr
uintptr_t *code_obj_addr
);

extern int append_awaited_by(
Expand Down
32 changes: 21 additions & 11 deletions Modules/_remote_debugging/asyncio.c
Original file line number Diff line number Diff line change
Expand Up @@ -716,7 +716,7 @@ find_running_task_in_thread(
}

int
get_task_frame(RemoteUnwinderObject *unwinder, uintptr_t task_addr, uintptr_t *frame_addr) {
get_task_code_object(RemoteUnwinderObject *unwinder, uintptr_t task_addr, uintptr_t *code_obj_addr) {
uintptr_t running_coro_addr = 0;

if(read_py_ptr(
Expand All @@ -733,7 +733,21 @@ get_task_frame(RemoteUnwinderObject *unwinder, uintptr_t task_addr, uintptr_t *f
return -1;
}

*frame_addr = running_coro_addr + (uintptr_t)unwinder->debug_offsets.gen_object.gi_iframe;
// note: genobject's gi_iframe is an embedded struct so the address to
// the offset leads directly to its first field: f_executable
if (read_py_ptr(
unwinder,
running_coro_addr + (uintptr_t)unwinder->debug_offsets.gen_object.gi_iframe, code_obj_addr) < 0) {
set_exception_cause(unwinder, PyExc_RuntimeError, "Failed to read running task code object");
return -1;
}

if (*code_obj_addr == 0) {
PyErr_SetString(PyExc_RuntimeError, "Running task code object is NULL");
set_exception_cause(unwinder, PyExc_RuntimeError, "Running task code object address is NULL");
return -1;
}

return 0;
}

Expand All @@ -746,7 +760,7 @@ parse_async_frame_chain(
RemoteUnwinderObject *unwinder,
PyObject *calls,
uintptr_t address_of_thread,
uintptr_t running_task_frame
uintptr_t running_task_code_obj
) {
uintptr_t address_of_current_frame;
if (find_running_frame(unwinder, address_of_thread, &address_of_current_frame) < 0) {
Expand All @@ -763,8 +777,6 @@ parse_async_frame_chain(
}
PyObject* frame_info = NULL;
uintptr_t address_of_code_object;

uintptr_t this_frame = address_of_current_frame;
int res = parse_frame_object(
unwinder,
&frame_info,
Expand All @@ -790,9 +802,7 @@ parse_async_frame_chain(

Py_DECREF(frame_info);

// Stop at the task's own frame. Code objects are shared by
// recursive calls, so they cannot identify it.
if (this_frame == running_task_frame) {
if (address_of_code_object == running_task_code_obj) {
break;
}
}
Expand Down Expand Up @@ -928,8 +938,8 @@ process_running_task_chain(
uintptr_t thread_state_addr,
PyObject *result
) {
uintptr_t running_task_frame = 0;
if(get_task_frame(unwinder, running_task_addr, &running_task_frame) < 0) {
uintptr_t running_task_code_obj = 0;
if(get_task_code_object(unwinder, running_task_addr, &running_task_code_obj) < 0) {
return -1;
}

Expand Down Expand Up @@ -961,7 +971,7 @@ process_running_task_chain(
}

// Add the chain from the current frame to this task
if (parse_async_frame_chain(unwinder, frame_chain, thread_state_addr, running_task_frame) < 0) {
if (parse_async_frame_chain(unwinder, frame_chain, thread_state_addr, running_task_code_obj) < 0) {
return -1;
}

Expand Down