Skip to content

GUI debugger can dispatch events to freed objects during terminal input #56

@alanbur

Description

@alanbur

While testing the nfix for SWI-Prolog/swipl-devel#1494 I also saw a separate SEGV involving the graphical debugger, xpce and terminal input dispatch.

I don't think this is caused by the fix for #1494 as this crash happens on a different path - xpce appears to dispatch a queued GUI event to an object that has already been freed while Prolog is blocked reading from user_input. The crash is not immediately reproducible. I saw it after using the graphical debugger with gspy/1, stepping through code, exiting/re-entering my app REPL a few times, and pressing keys in the terminal while the debugger confirmer was active.

Before the SEGV, xpce reported errors such as:

ERROR: pce(object) `@(11860891175632)' does not exist (@11860891175632/emacs_editor (freed))
ERROR: In:
ERROR:   [21] pce_principal:send_class(@(11860891175632),editor,event(@11860893716128/event))
ERROR:   [20] pce_principal:send_implementation('emacs_editor->event',event(@11860893716128/event),@(11860891175632)) at .../xpce/prolog/lib/emacs/window.pl:898
...

It then warned about a freed debugger object:

[PCE warning: unlink_from: No implementation for: ->input_focus
        [ 1] M @11860890885552/prolog_debugger (freed) ->input_focus(@off/bool)
]

The C stack was:

[3] inputFocusFrame() at packages/xpce/src/win/frame.c:1180
[4] pceExecuteGoal() at packages/xpce/src/ker/passing.c:874
[5] vm_send() at packages/xpce/src/ker/passing.c:1166
[6] sendPCE() at packages/xpce/src/ker/passing.c:1478
[7] sdl_frame_event() at packages/xpce/src/sdl/sdlframe.c:711
[8] CtoEvent() at packages/xpce/src/sdl/sdlevent.c:326
[9] ws_dispatch() at packages/xpce/src/sdl/sdlevent.c:820
[10] pceDispatch() at packages/xpce/src/itf/interface.c:635
[11] pce_dispatch() at packages/xpce/swipl/interface.c:2870
[12] PL_dispatch() at src/pl-fli.c:5461
[13] read_char() at packages/libedit/libedit4pl.c:1093
[14] el_wgetc()
[15] read_getcmd()
[16] el_gets()
[17] restore_signals() at packages/libedit/libedit4pl.c:504
[18] S__fillbuf() at src/os/pl-stream.c:695
[20] pl_read_string5_va() at src/pl-string.c:484

The Prolog stack was in my app REPL reading from user_input:

[18] system:read_string/5 <foreign>
[17] read_util:read_line_to_string/2
[16] utils:readLine/3
[15] utils:readLine/2
[14] utils:replLoop/2
[13] utils:repl/2
[12] p2k/0
[11] $toplevel:toplevel_call/1

ChatGPT's analysis is that libedit is blocked reading from user_input, calls PL_dispatch(), xpce processes a pending SDL frame /editor event and that event targets an emacs_editor / prolog_debugger object that has already been freed. So this looks like an xpce debugger/event lifetime or reentrancy issue, not an fd-cache issue.

That seems plausible but needs confirmation by someone who understands the code. If I see the problem again I'll log more details, but so far it appears to only happen at random.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions