ControlProvider cannot be moved — captured this in registered callbacks makes it unsafe

Open
#649 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
35/100
Issue type
Refactor
Clarity
Clearly specified
Activity status
Active
Tech stack
cpp

Research direction

Start with the ControlProvider implementation and main.cpp, then inspect ProcessGroupManager::deinitialize() and the control_provider and launch_manager Bazel targets. Verify that callback state has stable lifetime during drained transitions, Create() returns the provider by value, failure paths do not leak, and the build plus end-to-end ActivateRunTarget checks pass.

Written by the indexing model from the issue text.

Description

Description

Follow-up from discussion on #489 (comment).

Analysis results

ControlProvider registers three callbacks that capture this (activate_run_target/get_active_run_target handlers via RegisterHandler, and registerActiveRunTargetCallback), with no unregister path for any of them. Because of that, ControlProvider is currently non-movable and non-copyable, and Create() returns Result<ControlProvider*> — if it were moved, the callbacks would keep pointing at the old, now-dangling address (a real use-after-free, not just a theoretical one).

Solution

Proposed fix: move the callback-registering state (skeleton_, graph_, and the three setup*/handle* methods) into a private ControlProvider::Impl, with the callbacks capturing Impl* instead. ControlProvider then holds a single unique_ptr and becomes freely movable — moving it only moves the pointer, and Impl's address never changes. Create() can then return Result by value.

As a side effect this also fixes a leak on Create()'s failure paths (the current raw new is never deleted if a later setup*() call fails) and surfaces a lifetime dependency in main.cpp that the current code satisfies only by accident (scoping needs to keep ControlProvider alive through ProcessGroupManager::deinitialize()'s drain, since a drained transition can still invoke the registered callback).

Error Occurrence Rate

None

How to reproduce

Status: already implemented and verified — bazel build of control_provider + the full launch_manager binary succeeds, and manually verified end-to-end against a real Launch Manager daemon (2/2 ActivateRunTarget round trips over shared-memory IPC). Will open as a separate PR once #489 merges, per @danth's request on the thread above.

Supporting Information

No response

Classification

Minor

First Affected Release

not released (main)

Last Affected Release

not released (main)

Expected Fixed Release

before release (main)

Category
  • Safety Relevant
  • Security Relevant
Dominant language
C++
Stars
6
Forks
34
Avg merge
1d 23h
Merged PRs (30d)
83

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from eclipse-score/lifecycle

All issues in eclipse-score/lifecycle

Similar issues

More C++ issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.