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.
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( ), loop_handle_ timeouts( ) is being called *after* epoll_wait(), loop_handle_ timeouts( ) may free event sources.
ply_event_
but ply_event_
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. loop_handle_ timeouts( ) then runs, and calls on_boot_ splash_ idle(). This causes the event source object loop_handle_ timeouts( ) finishes, the
ply_event_
main.c:
referred to in the epoll_wait() event set to be freed and its reference
count set to zero. After ply_event_
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.