LINUX-PRODUCTION Contents

Debug Packages and Symbols in Production

Use debug symbols and debug packages to turn crashes into actionable stack traces. Learn when to install symbols, how to fetch them safely, and how to avoid bloating production images.

On this page

Why Debug Symbols Change Everything

A core dump without symbols often shows meaningless function names, missing line numbers, and unreadable stack traces. Debug symbols let you map memory addresses back to real functions and source lines. This turns “it crashed” into “it crashed here, for this reason”.

Symptom

  • Core dump backtrace shows “??” frames
  • Stack traces contain only memory addresses
  • Native crashes cannot be attributed to a library or function
  • Post-mortem debugging provides no actionable detail

Root Cause

  • Binary stripped of symbols (common in production builds)
  • Debug packages not installed
  • Separate debuginfo repository not enabled
  • Symbols not matching the exact binary version

Investigation

1) Confirm If a Binary Is Stripped

file /usr/bin/nginx

If it says “stripped”, debug symbols are not present.

2) Check If You Have a Core Dump Without Symbols

coredumpctl list
coredumpctl gdb PID

Inside gdb:

bt

If frames show “??”, symbols are missing.

Mitigation: Acquire Matching Debug Symbols

Key rule: symbols must match the exact package version of the binary and its libraries.

Debian/Ubuntu: dbgsym Packages

Ubuntu and Debian often provide separate dbgsym packages via a debug symbol repository.

Check package version:

dpkg -l | grep nginx

Install symbols (example pattern):

sudo apt install nginx-dbgsym

For libraries involved in the crash, install their dbgsym packages as well.

RHEL-based: debuginfo Packages

Enable debuginfo repositories and install debuginfo:

sudo dnf debuginfo-install nginx

List installed debuginfo:

rpm -qa | grep debuginfo

Operational Safety in Production

  • Do not permanently bloat production nodes with debuginfo unless required
  • Prefer reproducing in staging with the same build and symbols
  • If production analysis is required, install symbols temporarily and remove after investigation

Debug Symbols for Your Own Binaries

If you build native binaries, keep separate symbol files and store them in artifact storage.

Example build mindset:

  • Production binary can be stripped
  • Symbols stored separately and fetched when needed
  • Symbols versioned with build ID

Mitigation Workflow: Turning “Crash” Into “Fix”

  • Capture core dump
  • Confirm binary version and library versions
  • Install matching debug symbols (or fetch from artifact store)
  • Re-run gdb backtrace
  • Identify the crashing function and call chain
  • Correlate with deploy changes and inputs

Verification Checklist

After installing symbols, gdb backtrace should become readable:

coredumpctl gdb PID

Inside gdb:

bt
info threads
  • Stack frames show function names
  • Thread context visible
  • Crash location attributable to a library or module

Hardening Strategy

  • Maintain symbol artifacts for every production build
  • Ensure symbol/binary version matching discipline
  • Use staging reproduction as primary analysis environment
  • Keep debuginfo installation as an emergency-only step on prod

Why This Matters in Real Infrastructure

Many “random production crashes” are solvable, but only if you can see where they happen. Debug symbols turn post-mortem debugging into a reliable engineering loop. Without symbols, teams restart services blindly and accept recurring outages as fate.