From a2efd3c20853cac8ffd5c0abd00ab1258985fe1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maurycy=20Paw=C5=82owski-Wiero=C5=84ski?= Date: Fri, 8 May 2026 10:25:49 +0200 Subject: [PATCH] gh-149521: Do not update `last_profiled_frame` if it's not changed (GH-149522) (cherry picked from commit d36e5b86442bcf3b06876c91ff631c1f62632506) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Maurycy Pawłowski-Wieroński --- Modules/_remote_debugging/threads.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/Modules/_remote_debugging/threads.c b/Modules/_remote_debugging/threads.c index d775234b8d78d7..4daa5e5f92bcd9 100644 --- a/Modules/_remote_debugging/threads.c +++ b/Modules/_remote_debugging/threads.c @@ -450,12 +450,14 @@ unwind_stack_for_thread( set_exception_cause(unwinder, PyExc_RuntimeError, "Failed to collect frames"); goto error; } - // Update last_profiled_frame for next sample - uintptr_t lpf_addr = - *current_tstate + (uintptr_t)unwinder->debug_offsets.thread_state.last_profiled_frame; - if (_Py_RemoteDebug_WriteRemoteMemory(&unwinder->handle, lpf_addr, - sizeof(uintptr_t), &frame_addr) < 0) { - PyErr_Clear(); // Non-fatal + // Update last_profiled_frame for next sample if it changed + if (frame_addr != ctx.last_profiled_frame) { + uintptr_t lpf_addr = + *current_tstate + (uintptr_t)unwinder->debug_offsets.thread_state.last_profiled_frame; + if (_Py_RemoteDebug_WriteRemoteMemory(&unwinder->handle, lpf_addr, + sizeof(uintptr_t), &frame_addr) < 0) { + PyErr_Clear(); // Non-fatal + } } } else { // No caching - process entire frame chain with base_frame validation