fix(src): test_execution_sim_live GUI subprocess crash - root cause: imgui.set_window_focus exhausts main thread stack
The GUI subprocess (port 8999) crashes with 0xC00000FD =
STATUS_STACK_OVERFLOW when test_execution_sim_live triggers script
generation. Root cause: src/gui_2.py:render_response_panel called
imgui.set_window_focus('Response') directly during the render frame.
On Windows, the GUI subprocess main thread has only 1.94 MB of stack
(set by Python's PE header). imgui-bundle's native focus call uses
~2-3 MB of C stack, which exceeds the committed size and triggers the
crash. Same failure with both gemini_cli (mock subprocess) and gemini
(real SDK with gemini-2.5-flash-lite) - NOT provider-specific.
Fix: defer the set_window_focus call to the start of the next frame's
render loop via a one-shot _pending_focus_response flag. This mirrors
the existing _autofocus_response_tab pattern at gui_2.py:5353-5356
(which already uses a one-frame deferral via TabItemFlags_.set_selected).
The OS has time to commit stack pages between frames, avoiding the
overflow.
Files changed:
- src/app_controller.py: add _pending_focus_response flag init
- src/gui_2.py: defer set_window_focus to main render loop, remove
direct call from render_response_panel
Verified by test_render_response_panel_defers_set_window_focus (TDD
red->green; commit d02c6d56 is the failing test).
This commit is contained in:
@@ -874,6 +874,7 @@ class AppController:
|
||||
self._trigger_blink: bool = False
|
||||
self._is_blinking: bool = False
|
||||
self._blink_start_time: float = 0.0
|
||||
self._pending_focus_response: bool = False
|
||||
self._trigger_script_blink: bool = False
|
||||
self._is_script_blinking: bool = False
|
||||
self._script_blink_start_time: float = 0.0
|
||||
|
||||
+10
-7
@@ -1585,6 +1585,12 @@ def render_main_interface(app: App) -> None:
|
||||
app._process_pending_gui_tasks()
|
||||
app._process_pending_history_adds()
|
||||
if app.controller._process_pending_tool_calls(): app._tool_log_dirty = True
|
||||
if app._pending_focus_response:
|
||||
app._pending_focus_response = False
|
||||
try:
|
||||
imgui.set_window_focus("Response") # type: ignore[call-arg]
|
||||
except:
|
||||
pass
|
||||
#endregion: Process GUI task queue
|
||||
|
||||
render_track_proposal_modal(app)
|
||||
@@ -5534,13 +5540,10 @@ def render_response_panel(app: App) -> None:
|
||||
"""
|
||||
if app.perf_profiling_enabled: app.perf_monitor.start_component("_render_response_panel")
|
||||
if app._trigger_blink:
|
||||
app._trigger_blink = False
|
||||
app._is_blinking = True
|
||||
app._blink_start_time = time.time()
|
||||
try:
|
||||
imgui.set_window_focus("Response") # type: ignore[call-arg]
|
||||
except:
|
||||
pass
|
||||
app._trigger_blink = False
|
||||
app._is_blinking = True
|
||||
app._blink_start_time = time.time()
|
||||
app._pending_focus_response = True
|
||||
is_blinking = False
|
||||
blink_color = imgui.ImVec4(0, 0, 0, 0)
|
||||
if app._is_blinking:
|
||||
|
||||
Reference in New Issue
Block a user