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

debug/dwarf: StructField.ByteSize not set #21093

Closed
randall77 opened this issue Jul 19, 2017 · 5 comments
Closed

debug/dwarf: StructField.ByteSize not set #21093

randall77 opened this issue Jul 19, 2017 · 5 comments

Comments

@randall77
Copy link
Contributor

randall77 commented Jul 19, 2017

The fields StructField.ByteSize is not set. (ByteOffset is set.)
Demonstration:

package main

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

func main() {
	binary := os.Args[0]
	f, err := os.Open(binary)
	if err != nil {
		panic(err)
	}
	e, err := elf.NewFile(f)
	if err != nil {
		panic(err)
	}
	d, err := e.DWARF()
	if err != nil {
		panic(err)
	}
	r := d.Reader()
	for e, err := r.Next(); e != nil && err == nil; e, err = r.Next() {
		if e.Tag != dwarf.TagStructType {
			continue
		}
		t, err := d.Type(e.Offset)
		if err != nil {
			panic(err)
		}
		fmt.Printf("%s\n", t)
		s := t.(*dwarf.StructType)
		for _, f := range s.Field {
			fmt.Printf("  %d %d %s\n", f.ByteOffset, f.ByteSize, f.Name)
		}
	}
}

Build with go build and run it with no args. It reads its own DWARF info and prints out the info for all the struct fields.
Start of output:

struct runtime._type
  0 0 size
  8 0 ptrdata
  16 0 hash
  20 0 tflag
  21 0 align
  22 0 fieldalign
  23 0 kind
  24 0 alg
  32 0 gcdata
  40 0 str
  44 0 ptrToThis
struct runtime.typeAlg
  0 0 hash
  8 0 equal
struct runtime.interfacetype
  0 0 typ
  48 0 pkgpath
  56 0 mhdr

I think this is a bug with debug/dwarf, not the DWARF writer in the toolchain. I get the same behavior when reading DWARF from a C binary. (Or perhaps the C writer has the same issue?)

ByteSize might be kind of useful (or is .Type.Size() the recommended fallback instead?). At the very least, we should document that it isn't provided.

@heschik @derekparker

@randall77 randall77 added this to the Go1.10 milestone Jul 19, 2017
@heschi
Copy link
Contributor

heschi commented Jul 20, 2017

I don't think this is a bug in debug/dwarf, and probably isn't a bug at all. DW_TAG_member can optionally have a DW_AT_byte_size, but it's not required. From dwarf4:

If the size of a data member is not the same as the size of the type given for the data member, the
data member has either a DW_AT_byte_size or a DW_AT_bit_size attribute whose integer
constant value (see Section 2.19) is the amount of storage needed to hold the value of the data
member.

I'm not sure what circumstances would cause that to happen in any language, but it can't in Go AFAIK. So I think the short story is you should be looking at f.Type.Size().

@ianlancetaylor
Copy link
Contributor

Not important here, but to answer the question: the size of a data member differs from the size of the data member's type for a C/C++ bitfield.

@heschi
Copy link
Contributor

heschi commented Aug 16, 2017

@randall77 : anything further here?

@randall77
Copy link
Contributor Author

@heschik I think we should either add a comment to debug/dwarf, or better modify the code so that it does the StructField.ByteSize = Type.Size() for you.
The DWARF representation doesn't include the size when it is redundant with the type size because it is optimized to save space. But the debug/dwarf API doesn't have that constraint.

@gopherbot
Copy link

Change https://golang.org/cl/71671 mentions this issue: debug/dwarf: clarify StructField.ByteSize doc

@golang golang locked and limited conversation to collaborators Oct 18, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants