From b44a5afc9717dbe04ac15e53d7215ffe05072154 Mon Sep 17 00:00:00 2001 From: lightovernight <119399319+lightovernight@users.noreply.github.com> Date: Tue, 7 Oct 2025 21:51:46 +0800 Subject: [PATCH] upgrade isattach to status (#398) * fix an fatal error * fix bug : rerefrence invaild * implement better exception support * fix bug : might crash when eval executes * upgrade istattach to status * some fix * Update ceval.c --------- Co-authored-by: blueloveTH --- include/pocketpy/pocketpy.h | 4 ++-- src/debugger/dap.c | 24 ++++++++++++++++-------- src/interpreter/ceval.c | 2 +- src/public/PyException.c | 6 +++--- 4 files changed, 22 insertions(+), 14 deletions(-) diff --git a/include/pocketpy/pocketpy.h b/include/pocketpy/pocketpy.h index 02f618bf..fab5b4b3 100644 --- a/include/pocketpy/pocketpy.h +++ b/include/pocketpy/pocketpy.h @@ -659,12 +659,12 @@ PK_API bool StopIteration() PY_RAISE; #if PK_ENABLE_OS PK_API void py_debugger_waitforattach(const char* hostname, unsigned short port); -PK_API bool py_debugger_isattached(); +PK_API int py_debugger_status(); PK_API void py_debugger_exceptionbreakpoint(py_Ref exc); PK_API void py_debugger_exit(int code); #else #define py_debugger_waitforattach(hostname, port) -#define py_debugger_isattached() (false) +#define py_debugger_status() 0 #define py_debugger_exceptionbreakpoint(exc) #define py_debugger_exit(code) #endif diff --git a/src/debugger/dap.c b/src/debugger/dap.c index 811b40ae..13026a88 100644 --- a/src/debugger/dap.c +++ b/src/debugger/dap.c @@ -53,7 +53,8 @@ static struct c11_dap_server { c11_socket_handler toclient; bool isconfiguredone; bool isfirstatttach; - bool isattach; + bool isUserCode; + bool isAttached; bool isclientready; } server; @@ -441,7 +442,8 @@ void c11_dap_init_server(const char* hostname, unsigned short port) { server.isconfiguredone = false; server.isclientready = false; server.isfirstatttach = false; - server.isattach = false; + server.isUserCode = false; + server.isAttached = false; server.buffer_begin = server.buffer_data; server.server = c11_socket_create(C11_AF_INET, C11_SOCK_STREAM, 0); c11_socket_bind(server.server, hostname, port); @@ -480,7 +482,8 @@ void c11_dap_configure_debugger() { if(server.isfirstatttach) { c11_dap_send_initialized_event(); server.isfirstatttach = false; - server.isattach = true; + server.isAttached = true; + server.isUserCode = true; } else if(server.isclientready) { server.isclientready = false; return; @@ -491,7 +494,7 @@ void c11_dap_configure_debugger() { void c11_dap_tracefunc(py_Frame* frame, enum py_TraceEvent event) { py_sys_settrace(NULL, false); - server.isattach = false; + server.isUserCode = false; C11_DEBUGGER_STATUS result = c11_debugger_on_trace(frame, event); if(result == C11_DEBUGGER_EXIT) { // c11_dap_send_output_event("console", "[DEBUGGER INFO] : program exit\n"); @@ -515,14 +518,14 @@ void c11_dap_tracefunc(py_Frame* frame, enum py_TraceEvent event) { C11_STOP_REASON reason = c11_debugger_should_pause(); if(reason == C11_DEBUGGER_NOSTOP) { py_sys_settrace(c11_dap_tracefunc, false); - server.isattach = true; + server.isUserCode = true; return; } c11_dap_send_stop_event(reason); while(c11_debugger_should_keep_pause()) { c11_dap_handle_message(); } - server.isattach = true; + server.isUserCode = true; py_sys_settrace(c11_dap_tracefunc, false); } @@ -543,13 +546,18 @@ void py_debugger_waitforattach(const char* hostname, unsigned short port) { void py_debugger_exit(int exitCode) { c11_dap_send_exited_event(exitCode); } -bool py_debugger_isattached() { return server.isattach; } +int py_debugger_status() { + if(!server.isAttached) { + return 0; + } + return server.isUserCode ? 1 : 2; + } void py_debugger_exceptionbreakpoint(py_Ref exc) { assert(py_isinstance(exc, tp_BaseException)); py_sys_settrace(NULL, true); - server.isattach = false; + server.isUserCode = false; c11_debugger_exception_on_trace(exc); for(;;) { diff --git a/src/interpreter/ceval.c b/src/interpreter/ceval.c index ad5368c1..8480be2f 100644 --- a/src/interpreter/ceval.c +++ b/src/interpreter/ceval.c @@ -116,7 +116,7 @@ __NEXT_STEP: #if PK_ENABLE_WATCHDOG if(self->watchdog_info.max_reset_time > 0) { - if(!py_debugger_isattached() && clock() > self->watchdog_info.max_reset_time) { + if(py_debugger_status() == 0 && clock() > self->watchdog_info.max_reset_time) { self->watchdog_info.max_reset_time = 0; TimeoutError("watchdog timeout"); goto __ERROR; diff --git a/src/public/PyException.c b/src/public/PyException.c index 18c976cc..cc1008bb 100644 --- a/src/public/PyException.c +++ b/src/public/PyException.c @@ -12,7 +12,7 @@ void py_BaseException__stpush(py_Frame* frame, int lineno, const char* func_name) { BaseException* ud = py_touserdata(self); - int max_frame_dumps = py_debugger_isattached() ? 31 : 7; + int max_frame_dumps = py_debugger_status() == 1 ? 31 : 7; if(ud->stacktrace.length >= max_frame_dumps) return; BaseExceptionFrame* frame_dump = c11_vector__emplace(&ud->stacktrace); PK_INCREF(src); @@ -20,7 +20,7 @@ void py_BaseException__stpush(py_Frame* frame, frame_dump->lineno = lineno; frame_dump->name = func_name ? c11_string__new(func_name) : NULL; - if(py_debugger_isattached()) { + if(py_debugger_status() == 1) { if(frame != NULL) { py_Frame_newlocals(frame, &frame_dump->locals); py_Frame_newglobals(frame, &frame_dump->globals); @@ -225,7 +225,7 @@ char* py_formatexc() { VM* vm = pk_current_vm; if(py_isnil(&vm->unhandled_exc)) return NULL; char* res = formatexc_internal(&vm->unhandled_exc); - if(py_debugger_isattached()) py_debugger_exceptionbreakpoint(&vm->unhandled_exc); + if(py_debugger_status() == 1) py_debugger_exceptionbreakpoint(&vm->unhandled_exc); return res; }