Zig ReleaseSafe -fstrip while keeping debug symbols


I noticed that the resulting binary gets smaller if I let zig itself strip instead of relying only on llvm-strip

Bigger binary

zig build-exe -OReleaseSafe
(Backup unstripped binary)


zig build-exe -OReleaseSafe -fstrip

The problem with the ”smaller” workflow is that I lose the unstripped binary since zig never gave it to me in the first place.

Is there any way to get zig to do something like this?

zig build-exe -OReleaseSafe
(Backup unstripped binary)
zig -fstrip

So in short I’m asking if there is something like ”zip -fstrip” that takes an unstripped zig binary and removes symbol info?

Hey @jazzy, welcome to the forum!

Have you looked at these documents: Chapter 3 - Build system | ziglearn.org

Under the section “Outputting an Executable” there is the following:

The commands zig build-exe, zig build-lib, and zig build-obj can be used to output executables, libraries and objects, respectively. These commands take in a source file and arguments.

Some common arguments:

  • -fsingle-threaded, which asserts the binary is single-threaded. This will turn thread safety measures such as mutexes into no-ops.
  • -fstrip, which removes debug info from the binary.
  • --dynamic, which is used in conjunction with zig build-lib to output a dynamic/shared library.

Some of the documentation is a bit hectic right now because of how fast Zig is evolving, so please let me know if this doesn’t work for you!

1 Like


Thank you for the answer. I will examine using the build system and not just zig build-exe. It might leave unstripped symbols in an output directory even though the output binary is stripped.

My usecase is that I want to build a binary in releaseSafe mode, backup the unstripped binary, strip the binary I will use and deploy it. If it panics I want to load the coredump into gdb and attach debug symbols from my backed up unstripped binary so I can see where the panic occurred.

I see, so you’re trying to basically have two versions of the same thing so you can load in the unstripped version for debugging purposes.

Interesting. I haven’t come across this but I’ll do a bit of digging over the weekend. Thanks for clarifying - someone may know about this in the meantime.

1 Like

Thanks a lot. I will also do some digging.

This usecase is very common for c/c++ where you don’t want to deploy debug symbols but still be able to analyse coredumps.

1 Like

I understand this can also be achieved by storing the stripped binary and the symbol data in two separate files (this is how libc is usually distributed, right?).

That’s what I’m picturing as well. I’m trying to find example build.zig files that emit different strip options, and so I haven’t found one with what the OP is asking for, but I don’t see why this isn’t possible. According to this issue, they shouldn’t be able to have the same name in the same build: Having multiple executables with the same name in a build.zig should error · Issue #16460 · ziglang/zig · GitHub

But that implies you can just build multiple executables and condition them differently depending on the use case. I’m referring to executables here because @jazzy is using the command

zig build-exe -OReleaseSafe -fstrip

So this is the approach I would initially try.

I also read some stack overflow articles on re-gluing symbols, but I’m wondering if that’s even required here?


The reason the binary is smaller when zig handles stripping is that this boolean is available at compile-time and the standard library uses it to avoid compiling in the stack trace printing code if the binary will be stripped anyway. You can’t retroactively delete that code, it needs to not be emitted in the first place.


Thanks Andrew!

I’m closing this issue.