strip
Remove symbol table and debugging information from a binary
By CMD Script Team · 5 min read · Last updated
strip [OPTIONS] FILE...Options
| Flag | Description |
|---|---|
-s / --strip-all | Remove all symbols (the default action when no other option is given) |
-g / --strip-debug | Remove only debugging symbols and sections, keeping other symbol table entries |
-o FILE | Write the stripped result to FILE instead of modifying the input in place |
-p | Preserve the original file's permissions and timestamps on the output |
-K SYMBOL | Keep the named symbol even when stripping everything else |
-d | Remove debug symbols only (alias for --strip-debug on many platforms) |
Distribution compatibility
- Ubuntu
- Debian
- Fedora
- Arch
- macOS (via Xcode Command Line Tools)
What it does
strip removes the symbol table and debugging information from an object file or
executable, shrinking its size without changing its runtime behavior. Compiled binaries
normally carry metadata — function and variable names, line-number mappings, type
information — that debuggers and tools like nm and gdb rely on. strip deletes
that metadata, which is useful for reducing distribution size or making a binary harder
to reverse-engineer, but the operation is destructive and irreversible on the file it's
applied to.
Beginner examples
strip myprogram— remove all symbols frommyprogram, modifying it in placestrip -o myprogram.stripped myprogram— write the stripped result to a new file, leaving the original untouchedstrip -g myprogram— remove only debug symbols, keeping the regular symbol table- Check the size difference: run
size myprogrambefore and after stripping to see the reduction
strip -o release/myprogram build/myprogram
Advanced examples
- Strip every binary in a release directory as a build step:
find dist/ -type f -executable -exec strip {} \; - Keep one specific symbol while stripping everything else (useful for a required
plugin entry point):
strip -K plugin_init myplugin.so - Split debug info into a separate file before stripping, so it can be reattached later
with a debugger:
objcopy --only-keep-debug myprogram myprogram.debug strip --strip-debug myprogram objcopy --add-gnu-debuglink=myprogram.debug myprogram - Compare symbol visibility before and after stripping with
nm:nm myprogram | wc -lthen strip, thennm myprogram | wc -lagain.
strip --strip-debug -o app.release app.debug
Common mistakes
- Stripping the only copy of a binary and later needing to debug a crash, only to find
gdbhas nothing to work with — always keep an unstripped build artifact archived. - Assuming stripping improves runtime performance — it only reduces file size and removes debugging metadata; it does not touch the actual executable code paths.
- Stripping a static library (
.a) that's still needed for further linking against specific named symbols, which can break the link step if required symbols are removed. - Running
stripdirectly on a binary that's about to be signed (e.g. in a packaging or code-signing pipeline) after signing instead of before, invalidating the signature.
Tips
- Prefer
strip -o output originalover stripping in place, so you always retain an unstripped reference copy without extra bookkeeping. - Use
objcopyalongsidestripto preserve a separate debug-info file for post-mortem debugging of a stripped production binary. - Check the actual size savings with
sizeorls -lhbefore and after — the reduction varies a lot depending on how much debug info the compiler embedded (-gbuilds strip down much further than release builds without-g). - Only strip as a final packaging step, after all testing and debugging on that specific build has finished.
Best practices
- Never strip your only build artifact — keep an unstripped (or debug-info-preserving) copy in your build pipeline or artifact storage for future debugging.
- Strip release/distribution binaries as a deliberate, final packaging step, not as part of the everyday development build.
- Combine stripping with
objcopy --add-gnu-debuglinkworkflows when you need both a small production binary and the ability to debug crashes from the field later. - Automate stripping in CI/release scripts rather than doing it manually, so it's applied consistently and only to the intended artifacts.
Try it yourself
A simulated shell with a sample home directory — experiment freely, nothing leaves your browser. Type help to list supported commands.
Real-world use cases
- Reducing the size of binaries shipped in a Docker image or embedded firmware image where every megabyte matters.
- Preparing a release build of a commercial application where hiding internal function and variable names is a mild deterrent to casual reverse engineering.
- Shrinking build artifacts before uploading them to a package repository or CDN to cut storage and bandwidth costs.
- Producing a matched pair of a stripped production binary and a separate debug-info file so crash reports from production can still be symbolicated.
Common interview questions
- Is stripping a binary reversible? No — once the symbol table and debug info are removed from a file, they cannot be recovered from that file; the original unstripped build (or an extracted debug-info file) must be kept separately.
- Does stripping change how a program executes? No — it only removes metadata used for debugging and static linking, such as symbol names and line-number tables; the actual machine code and data sections are unaffected.
- Why would you strip a production binary? To reduce its file size for distribution or deployment, and to make casual reverse engineering slightly harder by removing descriptive symbol names.
- How can you keep debug capability for a stripped binary? Use objcopy to extract and save the debug information into a separate file before stripping, then link that debug file back to the stripped binary with --add-gnu-debuglink so a debugger can find it later without it being embedded in the shipped binary.
Frequently Asked Questions
Is stripping a binary reversible?
No. strip permanently removes the symbol table and debug information from the file it operates on. Once stripped, there's no way to recover that information from the binary itself — always keep an unstripped copy (or the separate debug info) if you might need to debug the binary later.
Why strip a binary at all?
Stripping reduces file size, which matters for distribution size, embedded/firmware images, and container image size, and it also makes reverse engineering somewhat harder by removing function/variable names and line-number debug info. It has no effect on runtime performance.
Does strip affect how the program runs?
No. Stripping only removes metadata used for debugging and linking against static libraries (symbol names, debug sections) — the actual executable code and data sections are untouched, so a correctly stripped binary runs identically to the unstripped version.
How do I keep debug info available without shipping a large binary?
Use objcopy to split debug info into a separate .debug file before stripping the main binary (objcopy --only-keep-debug, then strip, then objcopy --add-gnu-debuglink), so you can attach the debug info back with a debugger later without shipping it in the main binary.
Cheat sheet
Download a quick-reference cheat sheet for strip.