From a6a121ae86d2ca65cc9a6f35e03128f16de1b58f Mon Sep 17 00:00:00 2001 From: jim800121chen Date: Thu, 16 Apr 2026 15:40:30 +0800 Subject: [PATCH] fix(local-tool): suppress KneronPLUS DeviceGroup.__del__ access violation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Windows 上 bridge script 結束時 Python GC 呼叫 DeviceGroup.__del__ → kp_disconnect_devices 對已釋放的 native handle 操作 → OSError: access violation reading 0x00...0C。這是 KneronPLUS SDK 的 destructor 沒做 null check 的已知問題,不影響功能但會印嚇人的 stack trace 到 stderr。 修法: - 新增 _cleanup() 函式:明確 kp.core.disconnect_devices + 把 _device_group 設 None(讓 __del__ 成 no-op) - atexit.register(_cleanup) 確保 interpreter 關閉前 cleanup - main() return 後也同步呼叫一次(belt-and-suspenders) Co-Authored-By: Claude Opus 4.6 (1M context) --- local-tool/server/scripts/kneron_bridge.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/local-tool/server/scripts/kneron_bridge.py b/local-tool/server/scripts/kneron_bridge.py index 0e2120b..4f4bd95 100644 --- a/local-tool/server/scripts/kneron_bridge.py +++ b/local-tool/server/scripts/kneron_bridge.py @@ -1112,5 +1112,26 @@ def main(): _respond({"error": str(e)}) +def _cleanup(): + """Explicitly disconnect and clear _device_group before Python GC runs. + + KneronPLUS SDK's DeviceGroup.__del__ calls kp_disconnect_devices on a + native handle that may already be freed when the interpreter is shutting + down, causing 'OSError: access violation reading 0x00...'. By doing a + clean disconnect + setting the global to None here, __del__ becomes a + no-op (None has no __del__). + """ + global _device_group + if _device_group is not None: + try: + kp.core.disconnect_devices(_device_group) + except Exception: + pass + _device_group = None + + if __name__ == "__main__": + import atexit + atexit.register(_cleanup) main() + _cleanup() # also call synchronously in case atexit doesn't fire