Skip to content

Don't use a destroyed ClassLoader when deleting its instances - #240

Merged
mjcarroll merged 2 commits into
rollingfrom
mjcarroll/shared-loader-state
Nov 5, 2026
Merged

mjcarroll merged 2 commits into
rollingfrom
mjcarroll/shared-loader-state

Conversation

@mjcarroll

Copy link
Copy Markdown
Member

Deleters for managed instances captured the ClassLoader's this. Releasing an instance after its ClassLoader was destroyed was therefore a heap-use-after-free in onPluginDeletion().

Now the deleters share a small context with the loader, which the loader clears when it is destroyed. After that, a deleter just deletes the object. The library is never unloaded while instances exist, so the object's code is still loaded.

This fixes the lifetime half of #199 without the API change (no ClassLoader::Make()), so the rclcpp and demos patches aren't needed. The leak half of #199 was already fixed by #201 and #205. Thanks to @tylerjw for the original analysis.

Adds ClassLoaderLifetimeTest.instancesOutliveLoader. Without the fix, it fails under AddressSanitizer.

Deleters for managed instances captured the ClassLoader's `this`, so
releasing an instance after its ClassLoader was destroyed was a
heap-use-after-free. Have the deleters share a small context with the
loader instead; the loader clears it on destruction, after which a
deleter just deletes the object (the library is not unloaded while
instances exist).

Fixes the lifetime half of #199 without changing the API.

Signed-off-by: Michael Carroll <mjcarroll.oss@gmail.com>
@mjcarroll mjcarroll self-assigned this Nov 2, 2026
@mjcarroll
mjcarroll requested a review from ahcorde November 2, 2026 21:06
@mjcarroll

Copy link
Copy Markdown
Member Author

Pulls: #240
Gist: https://gist.githubusercontent.com/mjcarroll/02ce6e552b3cb21dc21b935717576890/raw/d56c85868137cdba115bbcb99de285742d1d1538/ros2.repos
BUILD args: --packages-above-and-dependencies class_loader
TEST args: --packages-above class_loader
ROS Distro: rolling
Job: ci_launcher
ci_launcher ran: https://ci.ros2.org/job/ci_launcher/20972

  • Linux Build Status
  • Linux-aarch64 Build Status
  • Linux-rhel Build Status
  • Windows Build Status

@fujitatomoya

Copy link
Copy Markdown

the fix looks good to me, but i do not have power to merge this.

@ahcorde

ahcorde commented Nov 5, 2026

Copy link
Copy Markdown
Contributor

Pulls: #240
Gist: https://gist.githubusercontent.com/ahcorde/cbcbcf0b98ea47c96e6fa534e0db1775/raw/d56c85868137cdba115bbcb99de285742d1d1538/ros2.repos
BUILD args: --packages-above-and-dependencies class_loader
TEST args: --packages-above class_loader
ROS Distro: rolling
Job: ci_launcher
ci_launcher ran: https://ci.ros2.org/job/ci_launcher/21020

  • Linux Build Status
  • Linux-aarch64 Build Status
  • Linux-rhel Build Status
  • Windows Build Status

…oader-state

Signed-off-by: Michael Carroll <mjcarroll.oss@gmail.com>

# Conflicts:
#	src/class_loader.cpp
@mjcarroll

Copy link
Copy Markdown
Member Author

stupid 10 hr timeout on the linux job, but rpr covers about the same.

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.

3 participants