EventsCBGExecutor segfaults when a timer is removed while its callback is running
メンテナーはふだん 1 日以内に返信
評価
調査の方向性
Start with timer_manager.hpp, especially the running timer's done callback and TimerQueue::remove_timer(); then read the shutdown path in events_cbg_executor.cpp. Reproduce with the linked gist and run the regression cases described in the issue. Done means callbacks can finish after timer removal or shutdown without a segfault, and the full rolling test suite passes.
索引モデルが issue の本文から書いたものです。
説明
Generated by Generative AI
Root-cause analysis, reproducer and text drafting with help of Claude Code (claude-opus-5-5)
Operating System:
Ubuntu 24.04 x86_64; rolling checked in the ros:rolling container.
ROS version or commit hash:
Jazzy: rclcpp 28.1.22 (binary packages); origin/jazzy 53fa7aee has the same code. Rolling: rclcpp 33.1.0 (binary packages); origin/rolling afe12bfa has the same code.
RMW implementation (if applicable):
rmw_fastrtps_cpp (default). Originally seen with rmw_zenoh_cpp; the bug isn't RMW-related.
RMW Configuration (if applicable):
No response
Client library (if applicable):
rclcpp
'ros2 doctor --report' output
No response
Steps to reproduce issue
- Gist: https://gist.github.com/spurnvoj/bd80f243880fe569a155421f7297ea3d
- git clone into ws/src, colcon build, bash src/cbg_timer_removal_repro/run.sh 10
- Setup: one node with a 1 s timer callback in EventsCBGExecutor; the timer is removed while that callback runs. Three modes:
- remove_node: executor.remove_node(), no shutdown
- sigint: Ctrl-C during spin()
- sigint_spin_some: Ctrl-C during a spin_some() loop
Expected behavior
The callback finishes, the removed timer isn't re-armed, and the process exits normally.
Actual behavior
SIGSEGV right after the callback returns, in all 3 modes, every run: Jazzy 10/10, rolling 5/5.
#0 rcl_timer_get_next_call_time () from /opt/ros/jazzy/lib/librcl.so
#1 ?? () from /opt/ros/jazzy/lib/librclcpp.so
#2 std::_Function_handler<void (), rclcpp::executors::cbg_executor::TimerQueue::get_ready_timer_callbacks()::{lambda()#1}>::_M_invoke(...) from /opt/ros/jazzy/lib/librclcpp.so
#3 ... ReadyEntity::get_execute_function() ... from /opt/ros/jazzy/lib/librclcpp.so
#4 rclcpp::executors::EventsCBGExecutor::run(unsigned long, bool) () from /opt/ros/jazzy/lib/librclcpp.so
Additional information
- Cause, timer_manager.hpp (jazzy 53fa7aee):
- the done callback of a running timer keeps a raw
TimerData *andthis(l. 388-396); TimerQueue::remove_timer()erases theunique_ptr<TimerData>(l. 218). That happens on node removal and inEventsCBGExecutor::shutdown(), which also destroys the wholetimer_manager(events_cbg_executor.cppl. 142, 159);- when the callback returns,
add_timer_to_running_map()uses the freed data; - the comment at l. 391-394 says the data stays valid; that holds only against
remove_if_dropped(), not againstremove_timer().
- the done callback of a running timer keeps a raw
- Ctrl-C path: the shutdown guard condition's handler runs synchronously on the thread calling
rclcpp::shutdown()(the signal handler thread). So shutdown frees state while worker threads are still running callbacks. Thetimer_manager.reset()comment, "no thread is working on it any more", doesn't hold. - Also reachable without shutdown: unloading a component (
ComponentManager→remove_node) while one of its timers runs. - Real-world impact:
component_container_events_cbgsegfaults on Ctrl-C when a timer callback is in flight. Found in the MRS UAV system (multi-component containers). - Related but different bugs: #3312 / #3313 (queued events of removed nodes outlive the unloaded library), #3186 (double removal on shutdown).
- Fix ready: https://github.com/fly4future/rclcpp/tree/fix/events-cbg-timer-removal (PR to follow):
- internal to the source files only, no ABI change, backportable to Jazzy;
- regression test with 3 cases: unfixed rolling 10/10 segfault per case, fixed 10/10 pass;
- full rolling test suite passes.
- 主要言語
- C++
- スター
- 815
- フォーク
- 572
- 平均マージ
- 6日 8時間
- マージ済み PR(30日)
- 20
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートなし
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
ros2/rclcpp のほかの issue
-
enhancement
難易度 2/5 1〜3時間 初心者へのやさしさ 70/100
メンテナーはふだん 1 日以内に返信
-
EventsCBGExecutor timers on ROS time stall after a backward /clock jump対応中かも @Yadunund が 5 日前に担当しました。 オープンbug
難易度 4/5 3〜5日 初心者へのやさしさ 30/100
メンテナーはふだん 1 日以内に返信
-
Late /clock delivery under use_sim_time stalls node now() for ~0.33 s (found via ros2_control controller time)対応中かも @JeremiahM37 が 3 日前に担当しました。 オープン
難易度 5/5 1週間以上 初心者へのやさしさ 10/100
メンテナーはふだん 1 日以内に返信
-
:farmer: Flaky EventsCBGExecutor test: reentrant callback group fails to run callbacks concurrentlyオープンbug
難易度 4/5 3〜5日 初心者へのやさしさ 35/100
メンテナーはふだん 1 日以内に返信
-
Copy constructor exception leaks intra-process message allocation対応中かも このイシューにリンクされたプルリクエストがオープン中、またはマージ済みです。 オープン
難易度 3/5 1〜2日 初心者へのやさしさ 35/100
メンテナーはふだん 1 日以内に返信
似ている issue
-
難易度 1/5 1時間未満 初心者へのやさしさ 88/100
メンテナーはふだん 1 日以内に返信
-
(S1 - Need confirmation)
難易度 2/5 1〜3時間 初心者へのやさしさ 65/100
CleverRaven/Cataclysm-DDA#89182 ·
メンテナーはふだん 1 日以内に返信
-
ai_p2
難易度 2/5 1〜3時間 初心者へのやさしさ 84/100
ClickHouse/ClickHouse#126833 ·
メンテナーはふだん 1 日以内に返信
-
clang:static analyzer
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
llvm/llvm-project#233598 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100