Skip to content

fix: prevent segfault when using MuJoCo viewer Reload button#120

Open
SHABRAWii wants to merge 1 commit into
unitreerobotics:mainfrom
SHABRAWii:fix/reload-segfault
Open

fix: prevent segfault when using MuJoCo viewer Reload button#120
SHABRAWii wants to merge 1 commit into
unitreerobotics:mainfrom
SHABRAWii:fix/reload-segfault

Conversation

@SHABRAWii
Copy link
Copy Markdown

Two race conditions crash the simulator on Reload:

  1. PhysicsLoop calls mj_deleteData/mj_deleteModel while the bridge threads are still reading from those pointers. Fix: add two std::atomic globals (g_bridge_pause_request / g_bridge_paused) as a pause/resume handshake. PhysicsLoop waits for the bridge to stop before freeing memory. UnitreeSdk2BridgeThread destroys and recreates the bridge on each reload instead of holding stale pointers forever.

  2. RecurrentThread::~RecurrentThread() destroys mFunc (the run() lambda) before sending pthread_cancel, and never sets mQuit. If the thread wakes between those two steps it calls the destroyed std::function and hits std::terminate(). Fix: replace RecurrentThread with a std::thread owned by RobotBridge, controlled by a std::atomic stop_flag_. pre_destroy() sets the flag and joins the thread — guaranteed clean exit before any destructor runs.

Two race conditions crash the simulator on Reload:

1. PhysicsLoop calls mj_deleteData/mj_deleteModel while the bridge
   threads are still reading from those pointers. Fix: add two
   std::atomic<bool> globals (g_bridge_pause_request / g_bridge_paused)
   as a pause/resume handshake. PhysicsLoop waits for the bridge to stop
   before freeing memory. UnitreeSdk2BridgeThread destroys and recreates
   the bridge on each reload instead of holding stale pointers forever.

2. RecurrentThread::~RecurrentThread() destroys mFunc (the run() lambda)
   before sending pthread_cancel, and never sets mQuit. If the thread
   wakes between those two steps it calls the destroyed std::function and
   hits std::terminate(). Fix: replace RecurrentThread with a std::thread
   owned by RobotBridge, controlled by a std::atomic<bool> stop_flag_.
   pre_destroy() sets the flag and joins the thread — guaranteed clean
   exit before any destructor runs.
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.

1 participant