System designTroubleshooting

RViz crashes when selecting a frame: fix the double free in plugins

RViz crashes with a double free when selecting a frame. The cause is mismatched libraries, not your robot definition; rebuild, run headless, or upgrade.

LumaSpec Vision10 min read Share on LinkedIn

On this page 10 sections
  1. 01Why does RViz crash the moment you select a frame?
  2. 02What do the two error messages actually tell you?
  3. 03Which cause is the most likely one?
  4. 04How do you confirm which library is mismatched?
  5. 05Can you fix it without upgrading the OS?
  6. 06Can the calibration run without the GUI at all?
  7. 07When is moving to a newer OS the only real fix?
  8. 08Which controller should run the rebuilt calibration stack?
  9. 09How do you verify the fix and keep it from coming back?
  10. 10Questions

RViz dies mid-calibration: your hand-eye plugin compiled, the panel opened, and the moment a frame is picked the terminal prints 'free(): invalid pointer' or 'double free or corruption (out)' and the process is gone with exit code -6. The pattern points at one thing: two halves of the same process were built against different versions of a shared framework. Below you get the ranked causes and the gdb check that names the mismatched library. You also get a rebuild procedure, a headless route to finish the calibration today, and the support-window arithmetic that decides when to leave the old OS behind. Controller specs for the rebuilt host close it out.

Why does RViz crash the moment you select a frame?

The crash is heap corruption, not a bad frame choice. Your hand-eye calibration plugin and one of the libraries already loaded in the RViz process were built against different versions of the same framework, so one of them releases memory the other allocated.

Both messages come from the C runtime's own consistency checks on the heap, and they fire after the damage is already done. Selection is simply the first code path that touches the damaged block, which is why a panel that opens fine kills the process on its first real action.

Your robot definition is not the suspect. A wrong model produces unknown-frame warnings and failed transform lookups, which print as messages you can read; it never trips the heap checks. And a clean compile proves nothing about runtime binding: compiling links names, while the crash comes from which copy of each library is actually loaded at run time.

What do the two error messages actually tell you?

'free(): invalid pointer' and 'double free or corruption (out)' are the same diagnosis. The heap checks found a pointer that was already released or never owned by this allocator, and they aborted the process with SIGABRT, which the launcher reports as exit code -6.

The arithmetic is one line: signal 6 is SIGABRT, the abort signal, and a negative exit code means death by signal rather than a normal exit status. Two checks, one disease. 'free(): invalid pointer' fires when the pointer handed over does not reference a block the allocator issued. 'double free or corruption (out)' fires when the bookkeeping around a block was overwritten — freed twice, or written past. Either way, a pointer crossed an ownership boundary between two builds of the same framework, and the runtime refused to continue on a heap it can no longer trust.

Which cause is the most likely one?

Rank the causes like this. First a source-built package compiled against different library versions than the prebuilt stack it runs on. Then two copies of one library loaded at different versions. Last, an actual bug in the plugin itself.

  1. Source-built plugin over prebuilt packages. The dominant pattern: the calibration plugin was compiled from source on a machine whose rviz and core libraries came prebuilt from the distribution, and the two never agreed on versions. Test: if anything in your workspace is self-built while the rest is packaged, suspect this first.
  2. Two copies of one framework library. The plugin links its own build of a library that rviz also loads, at a different version; both get mapped, and either can free what the other allocated. Test: list the shared libraries of the rviz binary and of the plugin (ldd does it on Linux) and look for any name that resolves to two different files.
  3. A duplicate dragged in by a camera SDK. SDKs for stereo and profiler cameras (the shop's 3D sensors fall in this group) often bundle their own copies of common frameworks, and the copies ride into any process that loads the SDK. Test: check what the SDK's own libraries link against before mixing them into the calibration process.
  4. A genuine bug in the plugin. Least likely when the abort sits in a plain free call at first selection; that signature points at the build, not the logic. Test: the calibration package's issue tracker, where this failure class has been reported and resolved at the OS level before.

How do you confirm which library is mismatched?

Reproduce under gdb and read the backtrace. The abort will sit in the C library's free path, and the frames above it name the component that made the releasing call — that component is one half of the mismatch.

  1. Get symbols for the crashing process, so the backtrace prints function names rather than raw addresses.
  2. Start rviz under gdb the same way your launch file starts it, pick the frame, and let it abort.
  3. Read the backtrace top down: SIGABRT raised from the allocator's checks, with the caller frames above naming the component that released the pointer.
  4. Compare versions: for every library that appears in both the rviz binary's and the plugin's dependency lists, check which file and version each resolves to. A name resolving to two different copies is the finding.

Write the pair down — component, library, the two versions — because the rebuild in the next section has to eliminate exactly that pair. Confirming costs minutes; rebuilding blind costs an afternoon, and if the rebuild misses the real duplicate you have spent the afternoon for nothing.

Can you fix it without upgrading the OS?

Yes, usually. Delete the build artifacts and rebuild every package in your workspace from source against exactly the versions the prebuilt stack ships. The whole process then links one copy of each library, and the allocation-free pair lands inside the same code again.

Wipe the workspace's build and install folders — output only, never your captures — and rebuild. One version of each library per process is the entire rule, and a from-source rebuild of everything that links the suspect framework enforces it.

If the rebuild itself stumbles on conflicting dependencies, the dependency mismatch walkthrough resolves them step by step, and a plugin that refuses to load at all has its own load-failure diagnostics. Same family of problem, different symptom at the door.

Can the calibration run without the GUI at all?

Yes, and it sidesteps the crash completely. The fault fires inside the viewer process, so a calibration node that takes its frame names from launch parameters and runs headless never touches the broken code path — select nothing in RViz, capture, solve, and review the result file afterwards.

The solver needs three inputs and none of them is a dropdown: the frame names, the captured robot poses with their images or clouds, and the transform tree. Pass the names as parameters, run the captures from the same robot positions you would have taught anyway, and let the node write its result. Check the result in a fresh viewer session or straight from the printed transform. If the fresh session then complains that a fixed frame does not exist, that is an unrelated configuration slip with its own five-minute fix.

And if the solver itself dies mid-run, that is a different crash class — the solver shutdown diagnostics cover it.

When is moving to a newer OS the only real fix?

When a clean rebuild still aborts, the stack itself is the problem. Melodic closed its window in May 2023, Noetic in May 2025, so plan the move to a maintained pairing — a ROS 2 release on Ubuntu 22.04 or 24.04, or the Noetic bridge if the plugin has one.

support end = release year + standard window (years) Ubuntu 18.04 LTS: 2018 + 5 = April 2023 ROS Melodic: 2018 + 5 = May 2023 ROS Noetic: 2020 + 5 = May 2025

If the calibration package you use ships a Noetic release, that is the smallest step off Melodic: same ROS 1 interfaces, newer libraries, and it is the move that ended this exact crash where it was carried through. Treat Noetic as a bridge — its own window closed in May 2025 — and start new stations on a ROS 2 distribution, which the calibration tools must then support as well.

If the old host cannot take a newer OS at all, that is a hardware decision, not a software one. The next section is yours.

Which controller should run the rebuilt calibration stack?

The calibration host is an ordinary vision controller. It needs enough ports for camera, robot controller and PLC plus one spare for engineering access, enough memory for capture and solver, and hardware you can actually re-image when its OS window closes — spec it once, correctly.

Count ports before anything else: camera LAN, robot, PLC, engineering laptop. Memory follows the data, since captures and point clouds are what a hand-eye session stores. PoE on the camera ports removes an injector from the panel.

The two controllers below bracket the range, each number taken from its spec sheet: MV-VC3301H-128G66 with an Intel Core i3 processor, 8 GB memory, 5+ LAN ports and 4 built-in light channels; MV-VC5525-256G70-NN with 5+ LAN ports, PoE camera ports, 8 built-in light channels, 32 GB memory and PCIe expansion.

Vision controllersHikrobot MV-VC3301H-128G66 I3-8100, 8GB+128G SSD, No PoE, PCIe expansion supported, Incl. VM6200Pro licenseMV-VC3301H-128G66
LAN ports
5+ LAN ports
USB 3 ports
3-4 USB 3 ports
$2,419.00View part
Vision controllersHikrobot MV-VC5525-256G70-NN VC5000 Vision Controller, 12th-I5, 32GB+256G SSD, Supported PCIEMV-VC5525-256G70-NN
LAN ports
5+ LAN ports
USB 3 ports
3-4 USB 3 ports
$4,479.00 · quotedView and quote

8 GB carries a one- or two-camera hand-eye session with room to spare; 32 GB leaves headroom for dense clouds and long capture sets. Both are current production units. Browse the vision controllers and filter by ports and memory, or run the system configurator and let it walk the rest of the station.

How do you verify the fix and keep it from coming back?

Run the exact action that crashed — selecting the robot base or end-effector frame in the calibration panel — and then prove the result, not just the absence of the crash. Capture the poses, solve, and check the verification error against the tolerance your process requires.

The accuracy verification procedure is the test that proves the matrix before any robot moves with it; a fix that restores the GUI but still ships an unverified matrix is half done.

Keep it fixed with four habits:

  • Pin the versions. Record the framework versions the workspace was built against, in the same file as the calibration result.
  • Rebuild after every system update. A packaged library can change under a compiled plugin at any update; rebuild before the next calibration run.
  • One copy of each package. Never install a source-built duplicate of something the distribution already provides.
  • Record SDK bundles. Camera SDKs that carry their own library copies are the usual source of duplicates; write them into the commissioning notes.

Version pinning is the transferable lesson — the same discipline that stops edge inference crashes applies to this station unchanged.

Next step: run the rebuild this afternoon; if the host has to be replaced to reach a maintained OS, size it by the port count above or send the station's port list through the contact page.

Questions

Will I need to rebuild the camera driver too?

Only what you built from source on this machine. A driver installed as a binary package from the distribution's repository already matches the stack rviz links, so it stays as installed. Anything compiled in your workspace — the calibration plugin, camera drivers, communication nodes — gets rebuilt, because each one is a potential owner of the mismatched copy.

Can two versions of one library coexist in one process?

The loader can load both, and the process may run for hours without complaint. The corruption lands when an allocation made by one copy is released through the other, and because the heap only notices later, the abort appears at a seemingly unrelated action — often the first frame selection. One version per process is the safe rule.

Does the crash differ between eye-in-hand and eye-to-hand set-ups?

The crash follows the selection action, not the calibration type. Eye-to-hand set-ups typically hit it when picking the robot base frame; eye-in-hand set-ups hit it when picking the end-effector frame. Both choices run the same frame-picker code, so the diagnosis and the fix are identical for the two configurations.

How long can a station safely stay on the end-of-life stack?

Unsupported time accumulates risk rather than causing this crash by itself. Melodic stopped receiving fixes in May 2023 and Ubuntu 18.04's standard support ended in April 2023, so every month of operation adds exposure with no patches behind it. A rebuild that provably clears the crash lets you finish the project; a maintained OS is the condition for fixing anything new.

Do I lose my calibration result when I rebuild?

No. The rebuild deletes compiled output only, so captured poses, images and any solved transform file stay on disk. Back them up anyway: they are the record of time spent at the robot, and with them preserved you can re-solve on a new stack without re-teaching a single pose.