Comment 189 for bug 553745

Revision history for this message
In , James Hunt (jamesodhunt) wrote :

I think I've worked out what is going on here (and which caused me to
raise the erroneous bug 42285):

In ply_event_loop_process_pending_events(),
ply_event_loop_handle_timeouts() is being called *after* epoll_wait(),
but ply_event_loop_handle_timeouts() may free event sources.

I can reliabily force plymouthd to SIGSEGV (in various parts of the
code) by running the following:

  plymouth show-splash
  plymouth quit

I'm seeing epoll_wait() return with a single valid fd event.
ply_event_loop_handle_timeouts() then runs, and calls
main.c:on_boot_splash_idle(). This causes the event source object
referred to in the epoll_wait() event set to be freed and its reference
count set to zero. After ply_event_loop_handle_timeouts() finishes, the
now invalid source object pointed to by the epoll event data is
referenced (it now has a reference_count of 1), and the invalid event is
now processed with varying SIGSEGV scenarios ensuing.

Currently ply_event_loop_process_pending_events() can be summarized as:

1. get events.
2. handle timeouts.
3. reference event sources.
4. process events.
5. unreference event sources.

The attached patch changes this slightly to be effectively:

1. get events.
2. reference event sources.
3. handle timeouts.
4. process events.
5. unreference event sources.