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

cmd/compile: DWARF duplicated DW_TAG_formal_parameter for some functions #61357

Open
dev747368 opened this issue Jul 14, 2023 · 4 comments · May be fixed by #61529
Open

cmd/compile: DWARF duplicated DW_TAG_formal_parameter for some functions #61357

dev747368 opened this issue Jul 14, 2023 · 4 comments · May be fixed by #61529
Assignees
Labels
compiler/runtime Issues related to the Go compiler and/or runtime. Debugging NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Milestone

Comments

@dev747368
Copy link

What version of Go are you using (go version)?

$ go version
go version go1.20.4 linux/amd64

I can duplicate this starting with 1.18. Binary produced with go 1.17 doesn't seem to show this issue.

Cross compiling to arm64 (instead of amd64) also shows the same issue.

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GOARCH="amd64"
GOOS="linux"

What did you do?

package main

import "fmt"

func main() {
	fmt.Println("Hello")
}
readelf -wi hello | less
search for the "internal/poll.(*FD).Write" DW_TAG_subprogram entry

What did you expect to see?

Expected to see a subprogram entry with 4 DW_TAG_formal_parameter params (fd, p, ~r0, ~r1)

What did you see instead?

Th ~r0 and ~r1 formal params elements were duplicated:

 <1>: Abbrev Number: 3 (DW_TAG_subprogram)
       DW_AT_name        : internal/poll.(*FD).Write
       DW_AT_low_pc      : 0x4783e0
       DW_AT_high_pc     : 0x4788e9
       DW_AT_frame_base  : 1 byte block: 9c       (DW_OP_call_frame_cfa)
       DW_AT_decl_file   : 0x5
       DW_AT_external    : 1
 <2>: Abbrev Number: 18 (DW_TAG_formal_parameter)
       DW_AT_name        : fd
       DW_AT_variable_parameter: 0
       DW_AT_decl_line   : 369
       DW_AT_type        : <0x7da43>
       DW_AT_location    : 0x1492a (location list)
 <2>: Abbrev Number: 18 (DW_TAG_formal_parameter)
       DW_AT_name        : p
       DW_AT_variable_parameter: 0
       DW_AT_decl_line   : 369
       DW_AT_type        : <0x6af98>
       DW_AT_location    : 0x14970 (location list)
 <2>: Abbrev Number: 17 (DW_TAG_formal_parameter)     ***1st ~r0***
       DW_AT_name        : ~r0
       DW_AT_variable_parameter: 1
       DW_AT_decl_line   : 369
       DW_AT_type        : <0x698f1>
       DW_AT_location    : 0 byte block:  ()
 <2>: Abbrev Number: 17 (DW_TAG_formal_parameter)     ***2nd ~r0***
       DW_AT_name        : ~r0
       DW_AT_variable_parameter: 1
       DW_AT_decl_line   : 369
       DW_AT_type        : <0x698f1>
       DW_AT_location    : 0 byte block:  ()
 <2>: Abbrev Number: 17 (DW_TAG_formal_parameter)    ***1st ~r1***
       DW_AT_name        : ~r1
       DW_AT_variable_parameter: 1
       DW_AT_decl_line   : 369
       DW_AT_type        : <0x740bc>
       DW_AT_location    : 0 byte block:  ()
 <2>: Abbrev Number: 17 (DW_TAG_formal_parameter)    ***2nd ~r1***
       DW_AT_name        : ~r1
       DW_AT_variable_parameter: 1
       DW_AT_decl_line   : 369
       DW_AT_type        : <0x740bc>
       DW_AT_location    : 0 byte block:  ()
.....
@gopherbot gopherbot added the compiler/runtime Issues related to the Go compiler and/or runtime. label Jul 14, 2023
@cherrymui
Copy link
Member

cc @thanm @golang/compiler

@cherrymui cherrymui added NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. Debugging labels Jul 14, 2023
@cherrymui cherrymui added this to the Backlog milestone Jul 14, 2023
@mauri870
Copy link
Member

mauri870 commented Jul 15, 2023

Hi, I've been investigating this issue with the duplicated parameters, it seems to start with 1.18 and the issue still exists on tip.

I tried git bisect (1.17 good, 1.18 bad) and it complained that something broke between a merge and a commit. I could not find any related changes tho, might be that the good and bad revisions are not direct descendants of each other.

Here is a testcase for this issue:

// src/cmd/link/internal/ld/dwarf_test.go
func TestIssue61357(t *testing.T) {
	testenv.MustHaveGoBuild(t)

	mustHaveDWARF(t)
	t.Parallel()

	const prog = `
package main

import "fmt"

func main() {
	fmt.Println("Hello")
}
`
	_, ex := gobuildAndExamine(t, prog, NoOpt)

	die := findSubprogramDIE(t, ex, "internal/poll.(*FD).Write")

	found := processParams(die, ex)

	expected := "[fd:0:1 p:1:1 ~r0:2:2 ~r1:3:2]"
	if found != expected {
		t.Errorf("param check failed, wanted:\n%s\ngot:\n%s\n",
			expected, found)
	}
}

For go 1.17 (good revision) it returns:

[fd:0:1 p:1:1 ~r1:2:2 ~r2:3:2]

but I noticed that on newer versions it should be r0 and r1 instead.

For master this test yields [fd:0:1 p:1:1 ~r0:2:2 ~r1:3:2].

Also noticed that it is this particular line that generates the duplicated parameters.

@mauri870
Copy link
Member

mauri870 commented Jul 19, 2023

Did some testing on windows as well with dwarfdump, the debug information appears to be duplicated on the same way:

DW_TAG_formal_parameter
  DW_AT_name                  ~r0
  DW_AT_variable_parameter    yes(1)
  DW_AT_decl_line             0x0000016e
  DW_AT_type                  <GOFF=0x0006ebee>
  DW_AT_location              len 0x0000: 
DW_TAG_formal_parameter
  DW_AT_name                  ~r0
  DW_AT_variable_parameter    yes(1)
  DW_AT_decl_line             0x0000016e
  DW_AT_type                  <GOFF=0x0006ebee>
  DW_AT_location              len 0x0000: 
DW_TAG_formal_parameter
  DW_AT_name                  ~r1
  DW_AT_variable_parameter    yes(1)
  DW_AT_decl_line             0x0000016e
  DW_AT_type                  <GOFF=0x0007999a>
  DW_AT_location              len 0x0000: 
DW_TAG_formal_parameter
  DW_AT_name                  ~r1
  DW_AT_variable_parameter    yes(1)
  DW_AT_decl_line             0x0000016e
  DW_AT_type                  <GOFF=0x0007999a>
  DW_AT_location              len 0x0000: 

mauri870 added a commit to mauri870/go that referenced this issue Jul 22, 2023
Dwarf formal parameters for some functions appear more than once in the
final dwarf debug symbols. I believe there is an error up the chain
where the parameters are parsed and some of them are pushed more than
once.

I ended up implementing a simple dedup mechanism to get rid of the
duplicates up the chain, but this should be investigated deeper into the
dwarf generation pipeline in a follow up ticket.

The testing routine `findSubprogramDIE` was updated to panic in case it
received duplicated formal parameters since this bug probably existed
for quite a while and it was never discovered since this function
basically overwrites a map indexed by the var name.

A test has been added to cover this case as reported in the original
issue ticket.

Fixed: golang#61357
mauri870 added a commit to mauri870/go that referenced this issue Jul 22, 2023
Dwarf formal parameters appear more than once in the
final dwarf symbols for some functions. I believe there is an error
up the chain where the vars are created and some of them are pushed
more than once to the list.

I ended up implementing a simple dedup mechanism to get rid of the
duplicates up the chain, but this should be investigated deeper in
a follow up ticket in order to find the root cause.

The testing routine `findSubprogramDIE` was updated to panic in case it
received duplicated formal parameters since this bug probably existed
for quite a while and it was never discovered since this function
basically pushes into a map indexed by the var name.

A test has been added to cover this case as reported in the original
issue ticket.

Fixed: golang#61357
mauri870 added a commit to mauri870/go that referenced this issue Jul 22, 2023
Dwarf formal parameters appear more than once in the
final dwarf symbols for some functions. I believe there is an error
up the chain where the vars are created and some of them are pushed
more than once to the list.

I ended up implementing a simple dedup mechanism to get rid of the
duplicates up the chain, but this should be investigated deeper in
a follow up ticket in order to find the root cause.

The testing routine `findSubprogramDIE` was updated to panic in case it
received duplicated formal parameters since this bug probably existed
for quite a while and it was never discovered since this function
basically pushes into a map indexed by the var name.

A test has been added to cover this case as reported in the original
issue ticket.

Fixed: golang#61357
@gopherbot
Copy link

Change https://go.dev/cl/512197 mentions this issue: cmd/compile: fix duplicated dwarf parameters for some functions

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler/runtime Issues related to the Go compiler and/or runtime. Debugging NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Projects
Status: In Progress
Development

Successfully merging a pull request may close this issue.

5 participants