-
Notifications
You must be signed in to change notification settings - Fork 17.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
cmd/go: add -debug flag (default true) to control DWARF/etc info in binary #38777
Comments
I wonder if this would be a net win overall, assuming that using |
Here's one case where it could help build speed a lot, though - single production builds from scratch, such as those that happen inside Dockerfiles, or on CI/CD machines. Those often exclude debug information, and they rarely have a warm build cache, given that they're not developer machines. For the same reason, they tend to compile a lot of packages from scratch, so even saving 2% of the compiler's work would be noticeable. |
The compiler has |
I think that's what @josharian meant by "Then cmd/go would translate that into the appropriate compiler and linker flags". Also, I don't think it's quite as simple as doing I think |
FWIW, I don't think we can do that. I don't know how the go command would compute accurate build IDs that would come out the same for a build in which some inputs have expected-to-be-ignored DWARF info versus a build in which no inputs do. Those are different incoming file hashes, and I don't see how to generate the outgoing file hash in a way that gets the same answer in both cases. Builds will become nondeterministic based on the content of the cache. And debugging places where DWARF info accidentally does change other compile results will become very difficult. Even if you somehow know the set of inputs to use, deciding whether you have a cache hit would now require two lookups - one to check for a -dwarf=false build and one to check for a -dwarf=true build. It's all very complicated and not obviously worth the complexity. So if we make In contrast, if -debug=false meant only -ldflags=-w, that would be a clear win and have no caching complexity - do we know what percentage of compile time is spent on DWARF, versus what percentage of link time? If the main purpose of the flag is to be a clearer statement of intent, then only applying to the link step might be fine: |
IIRC 1–2%
I don’t know this number offhand, but I think people mainly disable DWARF for smaller binaries, not faster link (or compile) times. Faster builds is an accidental benefit.
I’m not so sure. ‘go test’ builds without DWARF, so in the common case in which people run tests before generating a binary (both locally and in CI/CD), it might actually be the DWARF-containing build that requires significant recompilation.
FWIW, a clearer statement of intent was my primary goal in filing this proposal. But as per above, I think we can also get faster builds. |
@jayconrod brought up the same point on the golang-tools call a few weeks ago, and it's true that I wasn't thinking of the pitfalls of forcing the build cache this way. |
Looking at the code, it looks like OmitDebug is only set for the package main in a test or in "go run", not recursively down the tree. So I don't think those are doing full rebuilds necessarily. Would be nice if we were already doing full recursive non-DWARF builds, of course, but I don't think we are. (There are also implications for using the pre-cgo-ed packages like net.a without a C compiler toolchain installed if we do the recursive no-dwarf.) It still seems like the linker is where the win mostly is. Does anyone want to gather numbers about how much speedup there is in compiler + linker, vs how much recompilation is incurred? |
Discussion here seems blocked on someone gathering specific numbers showing that adding this flag would be helpful in practice. Anyone interested? |
I just wanted to mention that in the past we started with nearly all DWARF generation in the linker, and we have moved a good portion to the compiler, and we are planning to move more. (Not sure how this will affect the decision here.) |
I can gather numbers, but it probably won't happen particularly soon. But to re-iterate, I think the primary value here is clarity, and performance benefits are secondary. |
I see the clarity increase for Go developers who want to build a binary without DWARF for size reasons. I suppose the performance numbers would let us decide whether to make Based on the conversation above, then, this seems like a likely accept with the caveat that we don't know exactly what the implementation will be. |
Disabling DWARF generation in the compiler speeds up compilation and reduces memory use by about 3% each. With HEAD at fb5c3ea, I ran
|
Thanks for the numbers, @josharian. I still wonder a bit about how much the overhead of a full rebuild with dwarf info later matters but maybe most people are just repeating one particular go command (like go test or go run), in which case you get a cached build on all the repeats anyway. |
No change in consensus, so accepted. |
In the C/C++ compiler world, one thing that I've seen is that the presence or absence of "-g" can cause unexpected differences in the code generated by the compiler (e.g. "cc -g -O myfile.c" produces different assembly from "cc -O myfile.c"). This has come up many times in nearly every compiler I've worked on. Once we have "-debug={true,false}" up and running for the Go compiler, I think it would be useful to enhance our tools testing to:
My 2 cents. |
GCC has a |
Many gophers know that they can strip DWARF from their binaries with
-ldflags=-w
. But this is fairly cryptic, and it doesn't give the compiler the opportunity to save time and space by not generating that DWARF in the first place.I propose we add support directly to cmd/go to say
-debug=false
or-dwarf=false
or the like. Then cmd/go would translate that into the appropriate compiler and linker flags.The text was updated successfully, but these errors were encountered: