Skip to content
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

dwarf/godwarf: Can't adjust rnglist offset when seeking past current CU #3861

Open
danipozo opened this issue Nov 17, 2024 · 0 comments · May be fixed by golang/go#70400
Open

dwarf/godwarf: Can't adjust rnglist offset when seeking past current CU #3861

danipozo opened this issue Nov 17, 2024 · 0 comments · May be fixed by golang/go#70400

Comments

@danipozo
Copy link

This issue is the root cause of parca-dev/parca#5291.

What's the issue

Calling godwarf.LoadTree with certain offsets in certain binaries can result in incorrect DWARF entries being read.

How to reproduce

First, download and decompress ClickHouse binary:

curl -LO https://s3.amazonaws.com/clickhouse-builds/24.10/2e054d555719f509b96e0cfea4d5f5819c69a61f/package_release/clickhouse
chmod +x clickhouse
./clickhouse --version

Then, compile this:

import (
	"debug/dwarf"
	"debug/elf"
	"fmt"

	"github.com/go-delve/delve/pkg/dwarf/godwarf"
)

func main() {
  path := "clickhouse"
  f, err := elf.Open(path)
  if err != nil {
    print(err)
    return
  }

  d, err := f.DWARF()
  if err != nil {
    print(err)
    return
  }

  // DWARF info reader
  reader := d.Reader()

   _, err = godwarf.LoadTree(0x139d6483, d, 0)
   if err != nil {
    fmt.Printf("errored: %v\n", err)
  }

You will get the following output:

errored: invalid rnglist offset 2858131463 (max 636512)

If, instead, you change the offset passed to LoadTree to 0x139d02d2 (the start of the compilation unit), the example works properly. Also, by print-debugging, I have checked that the offset that is read for the problematic entry matches the one outputted by llvm-dwarfdump.

Why does this happen

According to this comment in debug/dwarf, Reader.Next() sets the current unit when it passes by a compilation unit DWARF entry, and then uses the offset of the CU to adjust the rnglist offset when encountering one. If Seek() is called directly to an offset that is after the compilation unit DWARF entry, that information is not set and the offset is incorrect.

How to solve this

Probably, by finding the CU for an offset in the first call and then reusing the reader across recursive calls.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant