Hacker News new | ask | show | jobs
by rsc 1890 days ago
Maybe another day I will take the time to write a full-length blog post examining the bytes in a Go binary. Today I have other work planned and still intend to do it.

My points today are only that:

1. Go binary size has not gotten dramatically better or worse in any particular release and is mostly unchanged since Go 1.3.

2. Many claimed facts in the blog post are incorrect.

3. The linker is not "embedding random data" into Go binaries as you conjectured in the comment above.

Stepping back a level, you don't seem to be interested in engaging in good faith at all. I'm not going to reply to any more of your comments.

2 comments

I have no dog in this fight either way, I'm just very curious about the answer: if something like 30-40% in a Go executable that clocks in at more than a 100 megabytes is not taken up by either symbols, debug information or the pclntab, what exactly is in it? You mentioned "necessary metadata for garbage collection and reflection in a statically-compiled language" in a previous comment. Can you give some more details on what that means?
You can see the true size of the Go pclntab in ELF binaries using "readelf -S" and in Mac binaries using "otool -l". Its not zero.

One thing that did change from Go 1.15 to Go 1.16 is that we broke up the pclntab into a few different pieces. Again, it's all in the section headers. But the pieces are not in the actual binary's symbol table anymore, because they don't need to be. And since the format is different, we would have removed the old "runtime.pclntab" symbol entirely, except some old tools got mad if the symbol was missing. So we left the old symbol table entry present, with a zero length.

Clearly, we could emit many more symbols accurately describing all these specific pieces of the binary. But ironically that would just make the binary even larger. Leaving them out is probably the right call for nearly all use case.

Except perhaps trying to analyze binary size, although even there even symbols don't paint a full picture. OK, the pclntab is large. Why is it large? What are the specific things in it that are large? Symbols don't help there at all. You need to analyze the actual data, add debug prints to the linker, and so on.

That would make an interesting post, and perhaps we will write one like that. But not today.

> OK, the pclntab is large. Why is it large? What are the specific things in it that are large?

Is it reasonably easy to attribute individual entries in pclntab to specific symbols? If so I'd love to add this capability to https://github.com/google/bloaty which already tries to do per-symbol analysis of many other sections (eh_frame, rela.dyn, etc).

It's reasonably easy for a specific Go release, but the details can and often do change from release to release. At some point we may write a more detailed, general-purpose binary size analysis tool that could dump JSON for bloaty to import, but today that tool does not exist.
It's a mystery, not a lynch mob. Everyone reading is interested in knowing "huh, what is this stuff then?"
You must know that breaking down and verifying someone else's analysis is more time consuming than writing your own. Just like dealing with a bug in another person's code.

Given them the benefit of doubt that Go team is cautious about binary size. People have dug in to this. Sure, they could do a better job giving some breakdown, but claiming that they are careless deserves that kind of response.

Given a choice of their time, I would rather have them work on some other Go language problem. Most low hanging fruit has already been had. See [1] [2] [3]

[1] https://dave.cheney.net/2020/05/09/ensmallening-go-binaries-...

[2] https://dave.cheney.net/tag/performance

[3] https://dave.cheney.net/2016/04/02/go-1-7-toolchain-improvem...

Russ is totally right. Pretending the linker is embedding “random data” is just trolling.
I mean on everyone else's part.