Skip to content

refactor: remove manual timer resets from event loop callbacks in Fcitx5 module - #57

Closed
yvonshong wants to merge 1 commit into
LeonardNJU:masterfrom
yvonshong:fix/reset_bug_in_ubuntu2204
Closed

refactor: remove manual timer resets from event loop callbacks in Fcitx5 module#57
yvonshong wants to merge 1 commit into
LeonardNJU:masterfrom
yvonshong:fix/reset_bug_in_ubuntu2204

Conversation

@yvonshong

Copy link
Copy Markdown

Title

fix(fcitx5): fix SIGSEGV crash caused by resetting EventSourceTime timer inside its own
callback

Description

### Problem
When pressing/releasing the PTT key (e.g. F9) or when UI animation/polling timers trigger,   

Fcitx5 would crash with Signal 11 (SIGSEGV) at vocotype.so.

### Root Cause
In `VoCoTypeModule`, several `fcitx::EventSourceTime` timers (`ptt_release_timer_`,          

ptt_hold_timer_, recording_animation_timer_, voice_edit_poll_timer_, polish_poll_timer_,
edit_hint_timer_) called timer_.reset() inside their own Lambda callback.

In Fcitx5, resetting the `std::unique_ptr<EventSourceTime>` deletes the event source instance

that holds the running Lambda closure, triggering a Use-After-Free and crashing the Fcitx5 host
process.

### Solution
Remove explicit `timer_.reset()` calls from inside the timer callbacks. One-shot timers

returning false are properly managed and cleaned up by Fcitx5's event loop.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits.
Credits must be used to enable repository wide code reviews.

@yvonshong
yvonshong force-pushed the fix/reset_bug_in_ubuntu2204 branch from 0e3237a to a7c0d4f Compare August 30, 2026 12:30
@LeonardNJU

Copy link
Copy Markdown
Owner

Thanks for the PR. The reported root cause is real, and your report helped us trace the timer ownership problem.

I am closing this PR rather than merging it as-is because simply removing the callback-side resets changes an important invariant: polling/animation paths need the timer member to become empty while the callback is running so they can reschedule safely. In particular, moving the reset into schedulePanelAnimationFrame() can still destroy the currently executing timer when that function is called recursively from its callback. The PR also contains unrelated key-cancellation behavior changes that should not be coupled to this fix.

The timer UAF is fixed on master in commit 207df16 using a callback-local ownership keepalive: the member is cleared immediately, while the executing EventSourceTime/closure stays alive through the rest of the callback. A real Fcitx EventLoop regression test was added as well.

Thank you for identifying the bug and contributing the patch.

@LeonardNJU LeonardNJU closed this Sep 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants