Ambiguous types in the debug/dwarf package

164 views
Skip to first unread message

Austin Clements

unread,
Mar 10, 2015, 10:39:50 PM3/10/15
to golang-dev
To return DWARF attribute values, the debug/dwarf package maps the DWARF attribute value "classes" to Go types (see https://golang.org/cl/7280 for a table). Unfortunately, this mapping is ambiguous in a way that makes it impossible to correctly interpret some DWARF attributes. For example, AttrStartScope (DW_AT_start_scope) can be either a constant or a rangelistptr. The attribute is interpreted differently depending on its class, but debug/dwarf maps both classes to int64, so the caller can't distinguish them.  AttrDataMemberLocation is similar.

I'd like to consider introducing a new Go type for lineptr, loclistptr, macptr, and rangelistptr attribute values [1]. This would violate the Go compatibility guarantee, but I consider the current interface a bug since it can't be used correctly. This change would break any users of the debug/dwarf package that use *ptr-valued attributes (see figure 20 in DWARF v4 for a list). However, debug/dwarf only yesterday gained support for decoding line tables and doesn't yet support decoding any of the other tables referenced by these attributes, so I suspect use of these attributes is not widespread.

I'd like to get people's thoughts on this problem.


[1] We only need one type for these four classes, since DWARF attribute data itself doesn't distinguish between them. For DWARF 2, which lacked *ptr classes and used constants instead, we could use a table of attributes for which constants should be upgraded to *ptrs.

minux

unread,
Mar 10, 2015, 10:46:57 PM3/10/15
to Austin Clements, golang-dev
Hi Austin,

I don't have an opinion on the issue you mentioned. I'm just curious what's your end goal for
the debug/* changes? Just bring debug/dwarf updated to DWARF v4? Or, are you working on
a debugger for Go? Make cmd/gc generate better dwarf? Or make runtime use dwarf for certain
tasks? Or something else?

Thanks.

Austin Clements

unread,
Mar 11, 2015, 11:03:41 AM3/11/15
to minux, golang-dev
Hi Minux. I've been using debug/dwarf to build performance analysis tools. In particular, I recently built a tool to annotate the garbage collector source with memory load latency distributions, for which I built a DWARF line table reader. That meant there were n line table readers, for n >= 2, built within the Go team alone, so we decided it was about time to merge the best parts of each into the standard dwarf package. That's now in master, but it led to documentation improvements, which led to us realize that there was a semantic ambiguity in the types used by for DWARF values.

I may also work on making cmd/gc generate better DWARF, since the unwind tables we generate right now appear to be incompatible with both Linux perf and VTune.  However, it's unlikely that would be related to debug/dwarf changes.

Ian Lance Taylor

unread,
Mar 11, 2015, 11:07:46 AM3/11/15
to Austin Clements, minux, golang-dev
On Wed, Mar 11, 2015 at 8:03 AM, 'Austin Clements' via golang-dev
<golan...@googlegroups.com> wrote:
>
> I may also work on making cmd/gc generate better DWARF, since the unwind
> tables we generate right now appear to be incompatible with both Linux perf
> and VTune. However, it's unlikely that would be related to debug/dwarf
> changes.

For what it's worth, ELF unwind tables (the contents of the .eh_frame
section) are almost but not quite DWARF (the DWARF version is the
.debug_frame section).

Ian

Austin Clements

unread,
Mar 11, 2015, 11:14:22 AM3/11/15
to Ian Lance Taylor, minux, golang-dev
Yes. I haven't really looked into the underlying problem yet. It may be as simple as these tools only supporting .eh_frame, but I thought they could also use .debug_frame.

Austin Clements

unread,
Mar 11, 2015, 11:29:11 AM3/11/15
to golang-dev
Alternatively, we could keep the types as they are and add a field to the Field struct that records the DWARF class of the value. This would be *almost* redundant with the Go type, except in these ambiguous cases (it could also be used to distinguish block from exprloc, though as of DWARF v4 there are no attributes for which those are ambiguous). This is not as clean as keeping this information in the Go type alone, but adding struct fields is specifically allowed by the Go 1 compatibility guarantee.

minux

unread,
Mar 11, 2015, 11:36:38 AM3/11/15
to Austin Clements, golang-dev


On Mar 11, 2015 11:29 AM, "'Austin Clements' via golang-dev" <golan...@googlegroups.com> wrote:
> Alternatively, we could keep the types as they are and add a field to the Field struct that records the DWARF class of the value. This would be *almost* redundant with the Go type, except in these ambiguous cases (it could also be used to distinguish block from exprloc, though as of DWARF v4 there are no attributes for which those are ambiguous). This is not as clean as keeping this information in the Go type alone, but adding struct fields is specifically allowed by the Go 1 compatibility guarantee.

This seems better. We normally don't break user programs even when fixing bugs (e.g. CL 6225048, the original structure definition is definitely wrong and couldn't do anything useful at all, but we still preserve it for the sake of backward compatibility)

Russ Cox

unread,
Mar 11, 2015, 4:43:29 PM3/11/15
to minux, Austin Clements, golang-dev
I believe we should add 'type Class int', a list of values, 'Class Class' to type Field, and func (e *Entry) AttrField(a Attr) *Field  as an alternative to (*Entry).Val that returns the *Field struct, so that callers can still do a lookup and then inspect the Class as desired. This seems like it will scale better than having to add new kinds of integers every time this happens (and it has happened before, so it will happen again). The Class is not quite the form encoding, since for example all the formRef2, formRef4, etc would be one ClassRef.

Russ

Reply all
Reply to author
Forward
0 new messages