The symptom is distinctive: a hand-eye or camera-calibration GUI starts fine, the robot connects, the panel appears — and the instant you click create target, draw a chessboard, or select an image topic, the whole process dies with exit code -11. That code is SIGSEGV, a segmentation fault. If you are doing this on a ROS-based cell, the crash usually surfaces in the visualization tool, which makes it look like a GUI bug. It almost never is. It is a native library version conflict, and it is fixable without rebuilding your workstation.
This guide is for engineers integrating cameras and calibration tools on Linux, especially where a source-built package shares a process with distribution-provided libraries. You will learn to read the backtrace, prove which duplicate library is at fault, and fix the linking cleanly. If your crash happens later, during the solve rather than the drawing, start instead with hand-eye calibration solver crash: diagnose the sudden shutdown.
Symptom and what exit code -11 means
The crash report names the process, a pid, and exit code -11. Negative exit codes are signals; -11 is SIGSEGV. The tool touched memory it should not have, which in this context means one of two things:
- Two builds of OpenCV are loaded in one process, and a call built against one version resolved into the other.
- One OpenCV is loaded, but it sits on two copies of the math library underneath it — typically OpenBLAS — and the symbol versioning disagrees.
The giveaway is timing. Everything before the fault is pure GUI and messaging code. The faulting action is the first one that executes an OpenCV image operation: drawing a calibration board, warping a target image, or converting an incoming image topic. In the reported traces, the fault lands inside a board-draw call or inside cv::warpPerspective, reached from whatever image processing bridge your stack uses.
Get a backtrace first, not a log
The log file the launcher promises often does not exist; the process died before writing it. Do not chase logs. Chase the backtrace:
- Enable core dumps for the shell:
ulimit -S -c unlimited. - Run the tool under gdb:
gdb --args <the exact command from the crash report>. - Let it crash, then type
btfor the stack trace. - If the GUI refuses to open under gdb, enable core dumps as above, let it crash outside the debugger, and open the core file with gdb afterwards.
The two or three frames that matter name the shared library file the faulting call lives in. That file name is your diagnosis: compare its version against what your code was compiled against.
Confirm the duplicate library
With the process paused under gdb, list what it actually loaded:
Or, while the GUI is alive, inspect the loaded-library maps of the running process and grep for opencv and blas. You are looking for two different version numbers of libopencv_core or libopencv_imgproc, or two OpenBLAS copies. Any one of those duplicates explains the segfault: the process built against one ABI called into another, and a struct layout or symbol changed between them.
The classic source of the duplicate on ROS workstations is an image-transport bridge built against one OpenCV while the rest of the stack, and the calibration plugin you added from source, were built against another. The same collision appears outside robotics whenever a vision app links a private OpenCV but loads a plugin linked against the system one.
Fix the linking
You have three options, in order of preference.
1. Build everything against one OpenCV
Point the calibration package's CMake at the OpenCV the rest of the process uses, clear the cached CMake paths so nothing silently keeps the old one, and rebuild only that package. This is the surgical fix: no uninstall, no workstation-wide change. If a dependency refuses to build against the system copy, you have found which package is pinning the conflict.
2. Remove the second copy
When a source-built OpenCV is the odd one out and nothing else on the station truly needs it, uninstall it and rebuild the calibration stack against the distribution copy. This is the blunt path, and it is the one that resolved the original report. It costs a rebuild of the packages that linked the private build — often just the calibration plugins.
3. Split the process
If one component truly must keep a private OpenCV, stop sharing a process with it. Publish images from a small acquisition node built against the private copy, and let the calibration tool consume the topic using the system copy. This is the standard recipe for keeping a custom OpenCV for acquisition while the rest of the stack stays on the distribution one.
For the related class of failure where a bridge silently picks the wrong OpenCV at runtime, see hand-eye calibration build errors: resolve dependency mismatches; the same CMake hygiene applies.
The OpenBLAS variant
On newer distributions the duplicate is not OpenCV at all but the math library beneath it. The backtrace still ends in an OpenCV image function, but the loaded-library listing shows two OpenBLAS versions, and the fault happens on the first matrix-heavy call. Upgrading the math library to a current release has fixed reported cases where no OpenCV duplicate existed. Check it before uninstalling anything: it is the cheapest fix when it applies.
Where the hardware sits in this
The camera itself is innocent. A camera stream that arrives at all is working; the crash is in the consumer's address space. That said, two habits prevent this whole class of problem at the station level:
- Keep one OpenCV version per machine image, pinned, and rebuild the image rather than patching libraries on a live station. A vision controller you control the software image of makes this policy enforceable across cloned stations.
- Prefer a camera that delivers finished images over a standard interface, so acquisition never needs a custom-built library. A USB3 camera such as the LS-CMR-0166 streams through a standard USB3 stack, leaving no reason for a private vision build on the station.
- Sensor format
- 1/1.7"
- Interface
- USB3
- Resolution
- 12 MP
- Shutter
- Rolling
If you run acquisition and solving on one fanless box with multiple camera ports, a controller like the MV-VC3301H-128G66 gives you a fixed target image: build once against its system libraries, then clone.
- LAN ports
- 5+ LAN ports
- USB 3 ports
- 3-4 USB 3 ports
- Light outputs
- 4 built-in channels
- Memory
- 8 GB
For camera-side troubleshooting that also shows up in ROS tools — a dark image rather than a crash — see USB3 camera dark image in ROS tools: fix bandwidth fallback.
Prevention checklist
- Pin one OpenCV version per station image; record it next to the camera and driver versions.
- After any source build, run
lddon the resulting binary and check everylibopencv_*path points at the same version. - Enable core dumps (
ulimit -S -c unlimited) on development machines before you need them. - Keep acquisition and GUI in separate processes when a private library is unavoidable.
- Before collecting calibration samples, draw one target and subscribe once — the two actions that fault — so a linking problem surfaces in seconds, not after an hour of robot moves.
When the usual answer is wrong
If the backtrace shows a single, consistent set of libraries and the fault is still in an image call, stop chasing versions. A malformed image — zero-size, wrong stride, or a topic publishing an unexpected encoding — can segfault drawing code just as dead. Reproduce with a locally generated synthetic image; if that draws cleanly, the problem is the stream, not the linking. And if the crash comes at the solve step rather than the drawing, with samples already collected, the cause is more likely solver-side: work through eye in hand calibration pose selection: robot positions that work, because near-parallel pose sets destabilize solvers independently of any library issue.
One more pointer for teams mixing environments: the same collision appears when a graphical measurement suite calls OpenCV calibration through a wrapper, and why LabVIEW crashes when calling OpenCV calibrateCamera covers that variant. The diagnosis order is the same: backtrace, loaded-library listing, then deduplicate.
If you are unsure whether your station's camera, controller and library stack can coexist, describe the set-up on the contact page and we will review it with you before you order.
Questions
Why does the crash happen only when I click create target or select an image topic?
Those are the first calls that actually execute OpenCV drawing or image-warping code inside the GUI process. Everything before that — loading the panel, connecting to the robot — only touches higher-level code. The moment a function such as board drawing or perspective warping runs, the process resolves symbols from whichever duplicate OpenCV or math library was loaded first, and if the versions disagree, the call reads memory with the wrong layout and the process dies with SIGSEGV.
How do I see which OpenCV libraries a running process loaded?
Start the tool under gdb, break or simply let it run, then use info sharedlibrary and filter the output for opencv and blas. Outside a debugger, run cat on the process's maps file and grep for opencv while the GUI is alive. If you see two different version numbers of libopencv_core, libopencv_imgproc, or a math library like libopenblas, you have found the conflict. The backtrace symbols also name the exact file the faulting call came from.
Can I fix this without uninstalling my own OpenCV build?
Often yes, but not always. Try building the calibration package against the system OpenCV by pointing CMake at it and clearing cached paths, so only one copy exists in the process. If another dependency insists on your custom build and that build cannot be removed, you may have to rebuild the calibration stack against it, or run the conflicting component in a separate process, as the cv_bridge recipe describes. Uninstalling your source build and rebuilding the stack against the distribution copy is the blunt but reliable path.
Why does Ubuntu 20.04 crash when Ubuntu 18.04 shows a different trace?
The mechanism is the same: mismatched native libraries in one process. On 20.04 the usual culprit is an old OpenBLAS that some OpenCV builds link against, and upgrading that math library has fixed reported cases. On 18.04 the trace more often points directly at a system libopencv_imgproc of a different version than the one the calibration code expects. The diagnosis is identical either way: read the file names in the backtrace and compare them against what your code was built against.
Is the calibration result suspect after the crash is fixed?
Not because of the crash itself. Once a single consistent set of libraries is loaded and the tool completes, the solver math is unaffected by the earlier linking problem. Still verify the result as you always should: check the reprojection or residual output, and confirm the pose spread of your collected robot positions, since poor pose selection is a separate and more common cause of a bad calibration than any library issue.
Do smart cameras and vision controllers suffer the same problem?
They avoid it in the common case. A smart camera runs its inspection on the device with one vendor-maintained software stack, so there are no user-linked OpenCV copies to collide. A vision controller that you program yourself has exactly the same risk as any Linux workstation, so the backtrace-and-deduplicate procedure applies there too. Keep one OpenCV version per controller image and pin it when you clone stations.

