System designTroubleshooting

GigE camera crashes gst-launch with SIGSEGV: fix the network config

A GigE camera source crashing gst-launch with SIGSEGV is almost always IP or MTU network config, not GStreamer. The fixes, tests and packet math.

LumaSpec Vision10 min read Share on LinkedIn

On this page 10 sections
  1. 01What actually crashed
  2. 02Setting one: an address in the camera's subnet
  3. 03Setting two: a 9000-byte MTU on the camera link
  4. 04The packet arithmetic that picks the MTU
  5. 05Three more causes, in order of likelihood
  6. 06The fix from start to finish
  7. 07When the link itself is the ceiling
  8. 08When the crash really is software
  9. 09Checklist: prove the fix and keep it
  10. 10Questions

You ran a minimal gst-launch-1.0 pipeline with a GigE Vision camera source on an embedded board, and it died with Caught SIGSEGV before the first frame. The instinct is to debug GStreamer. The profitable move is to check the network first: in the field this crash is usually a host interface with no IP address in the camera's subnet, or a NIC MTU smaller than the packet size the camera negotiated. The source plugin gets nothing usable back from device discovery and dereferences it. Below are the two settings that clear it, the commands that set and prove them, the packet arithmetic that tells you when jumbo frames are mandatory, and the short path to follow if the crash survives a correct link.

What actually crashed

A SIGSEGV is a segmentation fault: the process touched memory it does not own. gst-launch-1.0 traps the signal, prints "Caught SIGSEGV" and keeps the process alive so a debugger can attach. GStreamer appears in the message only because it is the host process; the fault itself usually sits one layer down, in the vendor SDK that the camera source element wraps.

When discovery fails — no route to the camera, so the SDK's open call returns no device — an older plugin hands that empty result straight to the next call and faults. You can see the layer in one minute:

gdb gst-launch-1.0
(gdb) run <your pipeline arguments>
(gdb) bt

Frames at the top of the backtrace inside the SDK's enumeration or grab call, rather than in GStreamer core, mean the network is the suspect.

Setting one: an address in the camera's subnet

Take the classic factory arrangement: camera at 192.168.20.10 with mask 255.255.255.0, host interface at 192.168.20.1. Everything after that depends on those two lines being right.

ip addr show
sudo ip addr add 192.168.20.1/24 dev eth0
sudo ip link set dev eth0 up
ping -c 3 192.168.20.10

/24 is the mask 255.255.255.0 written as a prefix length. Read the camera's real address in its viewer or configuration tool before you choose the host address, then place the interface in that same subnet. The full procedure for cameras that live on another subnet, including the remote-IP settings, is in connect a GigE camera on a different subnet.

Make the address persistent in your distribution's network configuration, or the crash returns after the next reboot.

The camera's transport layer sends image data in UDP packets whose size it negotiates with the interface. A NIC left at the 1500-byte default caps that well below what a camera stream wants, and the mismatch shows up as incomplete frames — or, in a source plugin with weak error handling, as the same segmentation fault.

sudo ip link set dev eth0 mtu 9000
ip link show eth0
ping -M do -s 8972 -c 3 192.168.20.10

The ping carries 8,972 bytes of data: the 9,000-byte MTU minus 20 bytes of IP header and 8 of ICMP. A reply proves the whole path passes jumbo packets; "Message too long" means some interface or switch port between camera and host still sits at a smaller value — set the camera's packet size below whatever passed. The same mismatch seen as torn and missing frames, with its diagnostics, is in GigE incomplete frames from a driver and NIC MTU mismatch, and capping the auto-negotiated size is covered in GigE Vision packet size exceeding the MTU. If the interface refuses the change at all, getting jumbo frames working when the MTU is stuck at 1500 walks the driver and configuration paths.

The packet arithmetic that picks the MTU

image rate = width × height × bytes per pixel × frames per second packets per frame = image bytes ÷ (MTU − 52) throughput ceiling ≈ 125 MB/s × (MTU − 52) ÷ (MTU + 38)

The 52 bytes are the IP, UDP and camera-stream headers each packet carries; the 38 bytes are preamble, Ethernet header, checksum and inter-frame gap on the wire. This is a wire-efficiency estimate — real links land a few percent lower once the host pays for every packet.

First the crashing test pipeline itself: 640 × 480 mono at 10 fps.

640 × 480 × 1 byte × 10 = 3,072,000 B/s ≈ 3.1 MB/s, or 24.6 Mbit/s — about 2% of a gigabit link. Per frame: 307,200 ÷ 1,448 = 213 packets at the 1500 default, against 307,200 ÷ 8,948 = 35 packets at 9000. At 10 fps that is 2,130 packets per second versus 350, a 6× cut in the per-packet work the CPU and interrupt path pay — the reason embedded boards want jumbo frames even when the wire is nowhere near full.

Now the decision case, a 5 MP mono camera at full rate:

2,448 × 2,048 × 1 byte = 5,010,048 B ≈ 5.0 MB per frame. 5,010,048 × 24 fps = 120.2 MB/s. Ceiling at 1500 MTU: 125 × 1,448 ÷ 1,538 = 117.7 MB/s. Ceiling at 9000 MTU: 125 × 8,948 ÷ 9,038 = 123.8 MB/s.

120.2 MB/s does not fit under the 117.7 MB/s default-MTU ceiling, and against 123.8 MB/s it leaves 3% headroom — too little for a production line. Cap that camera at 20 fps (100.2 MB/s, 19% headroom) on one gigabit link, or move it to a 2.5, 5 or 10 GigE interface. That is the whole MTU decision in four lines of arithmetic.

Three more causes, in order of likelihood

Cause Quick test Fix
Camera on DHCP with no server, self-assigned into 169.254.0.0/16 Viewer or arp -n shows a 169.254.x.x address Set fixed IPs on camera and host, or give the host an address in that range
Several NICs; the route to the camera leaves the wrong port ip route get 192.168.20.10 names another interface Dedicate one NIC to the camera: GigE camera on multiple network interfaces
Plugin built against a different SDK release than the one installed gst-inspect-1.0 reports one version, the installed SDK another; backtrace ends in the plugin Pin plugin and SDK to one release: edge inference device crashes fixed with SDK version pinning

The first row is the classic fresh-out-of-box failure: a camera that never reached a DHCP server takes a link-local address, and a host still sitting on 192.168.x.x never sees it.

The fix from start to finish

  1. ip addr show — find the interface wired to the camera.
  2. Set the host address: sudo ip addr add 192.168.20.1/24 dev eth0.
  3. Raise the MTU: sudo ip link set dev eth0 mtu 9000, then read it back with ip link show eth0.
  4. Ping the camera: ping -c 3 192.168.20.10. No reply — stop and fix addressing before anything else.
  5. Prove the jumbo path: ping -M do -s 8972 -c 3 192.168.20.10.
  6. In the camera's transport settings, set the packet size at or below the MTU that passed.
  7. Set a fixed IP on the camera itself.
  8. Re-run the gst-launch-1.0 pipeline at exactly the caps that crashed.
  9. If it still faults, take the gdb backtrace; only then move to software.
  10. Persist the address and the MTU so a reboot cannot resurrect the crash.

Once one camera streams, the next limit is the shared link. Two cameras on one host NIC split the same 125 MB/s — the port and bandwidth budget for that layout is in two GigE cameras on one host — and the failure pattern when a line outgrows its switch is in machine vision network congestion transfer faults. Resend storms and overflowing host buffers after a bad MTU change have their own signature, covered in GigE camera buffer overflow errors.

On the hardware side, a dedicated NIC per camera removes the sharing question; GigE frame grabbers and the accessories finder cover the options. For a dedicated camera link that carries power on the same cable, a dual-port PoE GigE NIC is the usual choice:

Frame grabbersHikrobot MV-GE2002P Dual-port PoE NIC, full height V2.0MV-GE2002P
Interface
GigE
Ports
2 ports
$249.00View partBuild a system with it

The LS-FGB-0004 is a PCIe x4 card with four PoE GigE ports for hosts that need more camera links. New cameras for that link can be filtered by interface in GigE area scan cameras or the camera finder, and when the arithmetic says a gigabit link will not carry the frame rate, 5GBASE-T camera interface bandwidth, cables and distance covers the mid-step upgrade. A high-performance NIC driver also raises sustained throughput on embedded hosts; the measured gains are in GigE Vision high performance NIC driver.

Two cable builds cover most cells — a 3 m high-flex drag-chain cable with screw locks, and a 15 m RJ45 data cable with locking studs — both from camera data cables:

When the crash really is software

If the three network checks pass — address, plain ping, jumbo ping — and the backtrace ends in GStreamer core or in the plugin's own caps handling, the fault is in the software stack. The two usual suspects: a plugin compiled against a different SDK release than the one installed, fixed by pinning both to one version as in edge inference device crashes fixed with SDK version pinning; and a missing support library, which shows as a pipeline that builds but produces no video — camera connected but viewer shows no video. If your source element exposes a capture-error property, set it to skip so one lost frame drops instead of halting the pipeline — insurance, not a fix.

Two neighbors worth telling apart: a crash that appears only after frames flow, with horizontal tearing, points back at the link, per GigE camera streaked frames on an embedded board; and a segfault inside caps negotiation on a CSI camera rather than a network camera is its own problem, covered in OpenCV segmentation fault on a CSI camera.

Checklist: prove the fix and keep it

  • Host interface holds a static IP in the camera's subnet, and both addresses are written down.
  • NIC MTU at 9000 — or the board's maximum — and read back after a reboot.
  • Plain ping to the camera answers.
  • Blocked-size ping at 8,972 bytes answers.
  • Camera packet size set at or below the MTU, camera on a fixed IP.
  • Camera link dedicated; no plant traffic on that port.
  • Plugin and SDK pinned to one release.
  • After any switch or cable change, repeat the two pings before restarting production.

Run the pipeline at the caps that crashed it. When it streams, those settings carry into production unchanged. If you are specifying the next cell, the system configurator walks camera, cable and interface in one pass, and the contact page reaches the applications team for a specific camera or NIC question.

Questions

Why does a bad IP address crash GStreamer instead of printing an error?

GStreamer calls each element's state-change function, and a vendor camera source typically calls the SDK's device-open inside it. When discovery fails because the interface has no address in the camera's subnet, older plugin builds hand the empty device handle to the next call instead of returning an error, and the dereference faults before any frame exists. A backtrace that ends inside the SDK's enumeration or open call, rather than in GStreamer core, confirms the layer.

Does the NIC MTU have to be exactly 9000?

No. The rule is one line: the camera's packet size must fit inside the NIC MTU on every hop between camera and host. 9000 is the common ceiling on desktop NICs; several embedded boards stop at 8192 or 7200. Set the interface to its maximum, read the value back, then set the camera's packet size a little below it. A blocked ping at the chosen size tells you the limit immediately.

Can I leave the camera on DHCP?

Production lines should not. A camera that gets no DHCP answer falls back to a self-assigned address in 169.254.0.0/16, so the host needs an address in that range to reach it — and after a power cycle the address can change. Give the camera a fixed IP outside your plant LAN range, put the host interface in the same subnet, and record both addresses on the machine's network drawing so the next commissioning does not rediscover this crash.

My low-resolution test pipeline ran fine at the default MTU. Are jumbo frames still needed?

Below roughly 118 MB/s of image data the link still works at the default MTU, so test caps like 640 × 480 at 10 fps — about 3.1 MB/s — never expose it. Full-resolution streaming multiplies the load: the same sensor at 2448 × 2048 and 24 fps needs about 120 MB/s, which does not fit. Set the MTU and packet size once, at commissioning, and the question never returns.

How do I tell a network SIGSEGV from a plugin bug before debugging?

Spend two minutes on the link first: `ip addr show` for an address in the camera's subnet, a plain ping to the camera, and a blocked-size ping for the MTU. If all three pass, run the pipeline under gdb, let it crash, and read the backtrace. Frames inside the vendor SDK's open or grab call point back at the link; frames in GStreamer core or in caps negotiation point at the plugin.