Skip to content

debug/buildinfo: may use lots of memory if data segment is large #68592

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

Closed
prattmic opened this issue Jul 25, 2024 · 7 comments
Closed

debug/buildinfo: may use lots of memory if data segment is large #68592

prattmic opened this issue Jul 25, 2024 · 7 comments
Labels
NeedsFix The path to resolution is known, but the work has not been done. Performance
Milestone

Comments

@prattmic
Copy link
Member

Since https://go.dev/cl/514075, debug/buildinfo reads the entire "data segment/section" containing the buildinfo in one go, regardless of size.

Normally, DataStart returns the .go.buildinfo section, which should be a modest size (and we'll need all of it anyway). But if the binary is stripped, or simply not a Go binary, then as a fallback it returns the first loadable data segment, which could be arbitrarily large.

This can be painful for tools scanning binaries in low-memory environments (e.g., CI), as the data segment could be quite large.

This is conceptually similar to #68454, but more straightforward to fix as this is all internal and could do chunked reading.

cc @mknyszek @zpavlinovic

@prattmic prattmic added the NeedsFix The path to resolution is known, but the work has not been done. label Jul 25, 2024
@prattmic prattmic added this to the Go1.24 milestone Jul 25, 2024
@prattmic
Copy link
Member Author

prattmic commented Jul 25, 2024

But if the binary is stripped, or simply not a Go binary

Sorry, strip alone doesn't strip the section headers, so .go.buildinfo can still be found. strip --strip-section-headers will do so.

@gopherbot
Copy link
Contributor

Change https://go.dev/cl/601460 mentions this issue: debug/buildinfo: reuse buffer in searchMagic

@gopherbot
Copy link
Contributor

Change https://go.dev/cl/601457 mentions this issue: debug/buildinfo: add old-Go and not-Go tests

@gopherbot
Copy link
Contributor

Change https://go.dev/cl/601458 mentions this issue: debug/buildinfo: add test for malformed strings

@gopherbot
Copy link
Contributor

Change https://go.dev/cl/601456 mentions this issue: debug/buildinfo: improve format documentation

@gopherbot
Copy link
Contributor

Change https://go.dev/cl/601459 mentions this issue: debug/buildinfo: read data in chunks

gopherbot pushed a commit that referenced this issue Jul 29, 2024
Existing documentation is a bit sparse, and more importantly focuses
almost entirely on the old pre-1.18 format, with the new format as an
afterthought. Since the new format is the primary format, make it more
prominent.

Updates #68592.

Change-Id: I108ecde1b33650b4812fa5d278b08cb9197f6329
Reviewed-on: https://go-review.googlesource.com/c/go/+/601456
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Auto-Submit: Michael Pratt <mpratt@google.com>
gopherbot pushed a commit that referenced this issue Jul 29, 2024
There is currently no coverage for the pre-1.18 buildinfo format, or for
parsing non-Go binaries. Add basic tests for each of these.

Updates #68592.

Change-Id: Iec14d29ffc1392e46f592c0c7bebf2eb75f7d0d3
Reviewed-on: https://go-review.googlesource.com/c/go/+/601457
Reviewed-by: Cherry Mui <cherryyz@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Michael Pratt <mpratt@google.com>
gopherbot pushed a commit that referenced this issue Jul 29, 2024
Updates #68592.

Change-Id: I00c6c740ca0bdd19af24e08a219ec3c90196097e
Reviewed-on: https://go-review.googlesource.com/c/go/+/601458
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Auto-Submit: Michael Pratt <mpratt@google.com>
gopherbot pushed a commit that referenced this issue Jul 31, 2024
Allocating a new buffer for each chunk in searchMagic is very
inefficient. Refactor reading to allow us to reuse the same buffer for
each iteration.

This reduces the runtime of `go version` on a 2.5GB non-Go binary from
~1s and ~25MB RSS to ~250ms and ~15MB RSS.

For #68592.

Change-Id: Idae5c2c9b3b8a7158d5cc7f2f008998be75fd7af
Reviewed-on: https://go-review.googlesource.com/c/go/+/601460
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
@gopherbot
Copy link
Contributor

Change https://go.dev/cl/602435 mentions this issue: debug/buildid: treat too large string as "not a Go executable"

gopherbot pushed a commit that referenced this issue Aug 1, 2024
If the length does not fit in int, saferio.ReadDataAt returns
io.ErrUnexpectedEOF. Treat is as an invalid format.

Fixes #68692.
For #68592.

Cq-Include-Trybots: luci.golang.try:gotip-linux-386-longtest
Change-Id: Ie856f29c907fd10e6d9b7dfbb6f0d8008a75a1c6
Reviewed-on: https://go-review.googlesource.com/c/go/+/602435
Auto-Submit: Michael Pratt <mpratt@google.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
NeedsFix The path to resolution is known, but the work has not been done. Performance
Projects
None yet
Development

No branches or pull requests

3 participants