gocore: explicitly load symbols from executable ELF file

This fixes partial typing fails when the core in question is complete
(meaning: no section has Filesz != Memsz). Such cores can be triggered
on Linux by writing (see core(5)):

  echo 0x3f > /proc/self/coredump_filter

In this case, none of the mem mappings are backed by the executable file
on disk. This meant that the previous readSymbols implementation only
reads the core file (which it ignored anyway).

Instead of looping over the mappings, read the symbols explicitly from
the executable.

I added a test which fails before my change. I had to refactor the
testing code a little bit to make it easier to pass an environment
variable. Unfortunately, changing /proc/self/coredump_filter means
writing to a file. Pulling in a dependency on package os makes the
dominator tests panic. For now I've disabled these tests: we're not sure
it worked well anyway (it must have crashed for non-trivial programs).
There may need to be more improvements in general typing/walking before
re-enabling it. In principle, the dominator failure could be partially
avoided by using build tags and not running the dominator test when
coredump_filter doesn't need to be manipulated. But given what I wrote
before, I don't see why we should bother.

The history of this is interesting:

 - https://go.dev/cl/137375 is the last good change to this part of the
   code. It reads symbols from all loaded executables. Its CL
   description mentions that this is required for PIE and mixed (e.g.:
   Go/C++ binaries). Yet the PIE and (internal) mixed binary tests
   continue to pass with this change:

   - I found that PIE support didn't work and added it in
     https://go.dev/cl/618977 (with tests). Perhaps this is a reference
     to PIE support that was somehow removed in-between.
   - viewcore does not explicitly support mixed binaries, in the sense
     that it does not (attempt) to understand C objects. The PIE tests

 - https://go.dev/cl/506558 introduced the full core bug by replacing
   the read from all executable files with an iteration of the mappings.

Change-Id: I2538cd863da72a9ebfc9415b32a97bf962479b61
Reviewed-on: https://go-review.googlesource.com/c/debug/+/637415
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
3 files changed
tree: eaaf58e2411570dac5f6b8b063fe4392b9349bbc
  1. cmd/
  2. dwtest/
  3. internal/
  4. third_party/
  5. codereview.cfg
  6. CONTRIBUTING.md
  7. go.mod
  8. go.sum
  9. LICENSE
  10. README.md
README.md

Go Debug

Go Reference

This repository holds utilities and libraries for debugging Go programs.

WARNING! Please expect breaking changes and unstable APIs. Most of them are currently are at an early, experimental stage.

Report Issues / Send Patches

This repository uses Gerrit for code changes. To learn how to submit changes to this repository, see https://go.dev/doc/contribute.

The git repository is https://go.googlesource.com/debug.

The main issue tracker for the debug repository is located at https://go.dev/issues. Prefix your issue with “x/debug:” in the subject line, so it is easy to find.