Ship a binary full of symbols and you leak build paths for nothing; strip carelessly and your next crash report is useless. This guide gets you a smaller copy of a Linux object file or executable while keeping an unstripped recovery copy and, when useful, a separate debug file. The examples use GNU Binutils 2.42 from the installed Ubuntu packages: binutils-common:amd64, binutils-aarch64-linux-gnu and binutils-x86-64-linux-gnu. The generic strip command and both listed target-prefixed commands share the same installed manual page here.
Allow about fifteen minutes. You need a shell, a file in an object format the selected tool understands, and enough permission to read and write the directory. These commands modify files unless an output file is selected, so do not start with the only copy of a release binary.
Start with read-only checks. This does not need elevated privileges:
$ command -v strip
/home/linuxbrew/.linuxbrew/bin/strip
$ strip --version | head -1
GNU strip (GNU Binutils for Ubuntu) 2.42
$ file /path/to/program
/path/to/program: ELF 64-bit LSB pie executable, x86-64, ...
Use the strip that matches the file's target: x86_64-linux-gnu-strip for x86-64, aarch64-linux-gnu-strip for AArch64. A target-prefixed tool is useful in a cross-compilation workflow because the prefix documents which output format you intend. The installed version is 2.42 even though the executable's vendor wording may vary slightly.
Checkpoint: if file reports a script, text file or an architecture you did not expect, stop. Do not use strip as a general way to make arbitrary files smaller.
GNU strip rewrites the named object file in place. Make a copy before testing, and preserve the original metadata where practical:
$ cp --preserve=all /path/to/program /path/to/program.full
$ file /path/to/program.full
/path/to/program.full: ELF 64-bit LSB pie executable, x86-64, ...
Safety boundary: this is not optional ceremony. Full stripping can remove symbols that a debugger, profiler, crash reporter or post-mortem investigation needs. If the command produces an unusable result, restore the copy with an explicit replacement:
$ cp --preserve=all /path/to/program.full /path/to/program
That replacement changes the destination, so confirm both paths before running it. If the binary is owned by a service or protected directory, arrange the copy and later replacement through your normal deployment process. Do not add sudo merely because a command example contains a path you have not checked.
For a release artefact that still needs its ordinary symbols, start with --strip-debug, also available as -g, -S or -d:
$ strip --strip-debug -o /path/to/program.stripped /path/to/program.full
$ file /path/to/program.stripped
/path/to/program.stripped: ELF 64-bit LSB pie executable, x86-64, ...
$ test -s /path/to/program.stripped && echo 'non-empty output'
non-empty output
The -o form writes one stripped output file instead of replacing the input, and it accepts only one input object file. Use a new destination while you are checking the result, then install or rename it through an explicit deployment step. The command may reduce the file size, but the exact reduction depends on how it was built, so do not treat a size change as the only success test.
Compare symbols when the tool is available:
$ nm -C /path/to/program.full | head
$ nm -C /path/to/program.stripped | head
Some symbols can remain after debug-only stripping. That is expected: this mode targets debugging sections, not every symbol in the file. A failed nm check is not proof that strip failed; use file, the program's own tests and the relevant debugger or loader as well.
Use --strip-all, or its short form -s, when the consumer does not need symbols:
$ strip --strip-all -o /path/to/program.release /path/to/program.full
$ file /path/to/program.release
/path/to/program.release: ELF 64-bit LSB pie executable, x86-64, ...
$ /path/to/program.release --help
The final command is an application-specific smoke test; replace it with a harmless invocation supported by your program. Do not run an unknown binary just to see whether stripping worked. A successful strip does not guarantee an application retains every tool-specific feature, and a program that expects symbols for a plugin or diagnostic path may no longer behave as intended.
Keep the unstripped file outside the public release if it contains sensitive names or paths, but retain it in controlled storage. A stripped binary is not a security boundary: strings, code, metadata and other sections can still disclose information.
For a fully linked executable, the manual documents a two-file workflow: create a debug-only companion, strip the executable, then add a GNU debug link.
$ objcopy --only-keep-debug /path/to/program.full /path/to/program.debug
$ strip --strip-debug /path/to/program.full
$ objcopy --add-gnu-debuglink=/path/to/program.debug /path/to/program.full
$ file /path/to/program.full /path/to/program.debug
/path/to/program.full: ELF 64-bit LSB pie executable, x86-64, ...
/path/to/program.debug: ELF 64-bit LSB shared object, x86-64, ...
The debug filename extension is a convention, not a requirement. Keep the debug file available to the debugger and keep the stripped executable in the deployment package. This workflow is intended for fully linked files; it is not a substitute for preserving complete debug information from each incomplete object file.
Warning: do not delete program.debug until your symbol server or debugging workflow has stored it. Removing that file is irreversible unless another copy exists. If the final executable must be restored, copy the saved unstripped file back rather than trying to reconstruct removed sections.
--remove-section, --remove-relocations and --strip-section-headers can remove data that makes an object unusable. The manual specifically warns that inappropriate section removal may make the output unusable. Use these only with a documented format requirement and a tested recovery copy.strip can process archives, and --verbose lists modified object files, but a change to a library archive affects every consumer that links it. The deterministic archive switches -D and -U also affect archive member metadata; do not add either to a reproducible-build recipe without checking the build system's existing policy.program.full, and inspect the command and file type before trying another option. Elevated privileges do not fix a format mismatch.--strip-debug for debug removal, --strip-all for deliberate symbol removal.file and a harmless application-specific check.