Opened 3 years ago

Closed 3 years ago

#851 closed defect (fixed)

UI Demo sometimes crashes in display_cb_conn

Reported by: Jiri Svoboda Owned by:
Priority: major Milestone: 0.12.1
Component: helenos/unspecified Version: mainline
Keywords: Cc:
Blocker for: Depends on:
See also:

Description (last modified by Jiri Svoboda)

Occasionally UI Demo can crash with a stack trace like:

Kill message: Page fault: 0x00000028.
[/srv/taskmon(16)] taskmon: Task 71 fault in thread 0x84d83c48.
[/srv/taskmon(16)] taskmon: Executing /app/taskdump -t 71
[/app/taskdump(72)] Task Dump Utility
[/app/taskdump(72)] Dumping task '/app/uidemo' (task ID 71).
[/app/taskdump(72)] Loaded symbol table from /app/uidemo
[/app/taskdump(72)] Threads:
[/app/taskdump(72)]  [1] hash: 0x84d83c48
[/app/taskdump(72)] Thread 0x84d83c48: PC = 0x7015e131 (_end+1745828365). FP = 0x08173e28
[/app/taskdump(72)]   0x08173e28: 0x7015e131 (_end+1745828365)
[/app/taskdump(72)]   0x08173e48: 0x7015e229 (_end+1745828613)
[/app/taskdump(72)]   0x08173e68: 0x08059729 (ui_unlock+20)
[/app/taskdump(72)]   0x08173e98: 0x0805b6b4 (dwnd_pos_event+87)
[/app/taskdump(72)]   0x08173ee8: 0x0806096e (display_ev_pending+351)
[/app/taskdump(72)]   0x08173f48: 0x08060a6e (display_cb_conn+95)
[/app/taskdump(72)]   0x08173fc8: 0x7016476e (_end+1745854538)
[/app/taskdump(72)]   0x08173ff8: 0x7015c16c (_end+1745820232)
[/app/taskdump(72)] Address space areas:

(this is compiled with -O0). This would typically happen when a menu entry is selected.

Change History (4)

comment:1 by Jiri Svoboda, 3 years ago

Description: modified (diff)

comment:2 by Jiri Svoboda, 3 years ago

This is difficult to reproduce, sometimes it happens quite often, at other times it does not
happen at all.

I think this is caused by liberal destruction of windows in event handlers. Let's look at
the function dwnd_pos_event():

static void dwnd_pos_event(void *arg, pos_event_t *event)
{
        ui_window_t *window = (ui_window_t *) arg;

        /* Make sure we don't process events until fully initialized */
        if (window->wdecor == NULL)
                return;

        ui_lock(window->ui);
        ui_wdecor_pos_event(window->wdecor, event); // <=== Can destroy window here
        ui_window_send_pos(window, event); // <=== Can destroy window here
        ui_unlock(window->ui);
}

The window could be destroyed in ui_wdecor_pos_event() (e.g. if we click the close button) or
in ui_window_send_pos() (e.g. if we select a menu entry, which closes the menu).

comment:3 by Jiri Svoboda, 3 years ago

Since this is a use-after-free problem, it should be possible to make it reliably reproducible by overwriting the incriminated (window) structure when it's freed. This is easy to do manually. One could also make use of such debug feature in the memory allocator, if it were available. This might lead to finding more, similar, problems.

comment:4 by Jiri Svoboda, 3 years ago

Resolution: fixed
Status: newclosed

Fixed in changeset 0415776cc1c47e8ad449850f31b4bb6d3445bb33.

This was easy in the end.

  1. Save window→ui to use for ui_unlock() after the callback
  2. For dwnd_pos_event(), if window decoration claims event, do not deliver to window.
Note: See TracTickets for help on using tickets.