Skip to content

[Humble][macOS M2] bad_weak_ptr in nav2_util::LifecycleNode::createBond() due to unique_ptr with shared_from_this() #5335

@idesign0

Description

@idesign0

Bug Report: bad_weak_ptr Exception in nav2_util::LifecycleNode::createBond() on Apple Silicon (M2) – ROS 2 Humble

Description

While using nav2_util::LifecycleNode::createBond() in ROS 2 Humble on Apple Silicon (M2), I encountered a bad_weak_ptr exception during lifecycle node activation (e.g., in map_server, amcl).

After investigation and debugging via LLDB, I found the cause was the use of std::make_unique<bond::Bond>(...), while the Bond class internally calls shared_from_this(). Since the object is not owned by a shared_ptr, this leads to a bad_weak_ptr when bond_->start() is called.

System Info

  • Architecture: Apple Silicon M2
  • ROS 2 Version: Humble
  • Build Type: Source
  • OS: macOS 14.5 (24F74)

Steps to Reproduce

  1. Run any node using createBond() (e.g. map_server or amcl)
  2. Perform lifecycle transitions (e.g., configure → activate)
  3. Observe crash during activation: bad_weak_ptr

Backtrace / Logs

[map_server]: Caught exception in callback for transition 13
[map_server]: Original error: bad_weak_ptr
[WARN] [1751757540.736409772] [map_server]: Error occurred while doing error handling.
[FATAL] [1751757540.736417063] [map_server]: Lifecycle node map_server does not have error state implemented

Proposed Fix ✅

Change the member declaration in 'nav2_util::LifecycleNode'(#L207):

- std::unique_ptr<bond::Bond> bond_;
+ std::shared_ptr<bond::Bond> bond_;

Then, create the bond using 'std::make_shared' instead of 'std::make_unique' in lifecycle_node.cpp:

  bond_ = std::make_unique<bond::Bond>(
    std::string("bond"),
    this->get_name(),
    shared_from_this());

This resolves the 'bad_weak_ptr' exception during lifecycle node activation on Apple Silicon (M2), allowing nodes like 'map_server' and 'amcl' to activate correctly.

Side note:
On macOS, costmap plugins are not dynamically loaded automatically due to system library loading restrictions.
You need to manually set the following environment variable before launching Navigation2:

export DYLD_INSERT_LIBRARIES=$HOME/humble-ros2/install/nav2_costmap_2d/lib/liblayers.dylib

Without this, costmap plugins won’t load properly, which can lead to silent failures in costmap behavior.

Additional remark:
This plugin loading issue also affects MoveIt2 on macOS. Similar manual intervention with 'DYLD_INSERT_LIBRARIES' is required to ensure plugin libraries are properly loaded.

Output

Image

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions