https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93844
Bug ID: 93844 Summary: [debug] Incorrect scope for local variables Product: gcc Version: 10.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: go Assignee: ian at airs dot com Reporter: vries at gcc dot gnu.org CC: cmang at google dot com Target Milestone: --- Consider the following c example hello.c (based on gdb/testsuite/gdb.go/hello.go): ... #include <stdio.h> const char *st = "Shall we?"; int main (void) { printf ("%s\n", st); printf ("%s\n", "Before assignment"); { const char *st = "Hello, world!"; printf ("%s\n", st); } return 0; } ... when compiling and executing, we get first the value of the global variable, then the one of the local variable: ... $ gcc hello.c -g $ ./a.out Shall we? Before assignment Hello, world! ... Likewise, when debugging: ... Temporary breakpoint 2, main () at hello.c:8 8 printf ("%s\n", st); (gdb) p st $3 = 0x4005d4 "Shall we?" (gdb) n Shall we? 9 printf ("%s\n", "Before assignment"); (gdb) p st $4 = 0x4005d4 "Shall we?" (gdb) n Before assignment 11 const char *st = "Hello, world!"; (gdb) p st $5 = 0x0 (gdb) n 12 printf ("%s\n", st); (gdb) p st $6 = 0x4005f0 "Hello, world!" (gdb) ... Now, consider the equivalent program in go: ... package main import "fmt" var st = "Shall we?" func main () { fmt.Println (st) fmt.Println ("Before assignment") st := "Hello, world!" fmt.Println (st) } ... When compiling and executing, again we get first the value of the global variable, then the one of the local variable: ... $ gccgo hello.go -g $ ./a.out Shall we? Before assignment Hello, world! ... But when debugging, we fail to print the value of the global variable: ... Thread 1 "a.out" hit Temporary breakpoint 1, main.main () at hello.go:7 7 func main () { (gdb) p st $1 = 0x0 "" (gdb) n 8 fmt.Println (st) (gdb) p st $2 = 0x0 "" (gdb) n Shall we? 9 fmt.Println ("Before assignment") (gdb) p st $3 = 0x0 "" (gdb) n Before assignment 10 st := "Hello, world!" (gdb) p st $4 = 0x0 "" (gdb) n 11 fmt.Println (st) (gdb) p st $5 = 0x404e06 "Hello, world!" ... This is due to lack of scoping of the local variable. In the C case, the st local variable is scoped by a DW_TAG_lexical_block: ... <1><3c3>: Abbrev Number: 18 (DW_TAG_variable) <3c4> DW_AT_name : st <1><3d7>: Abbrev Number: 19 (DW_TAG_subprogram) <3d8> DW_AT_name : main <2><3f4>: Abbrev Number: 20 (DW_TAG_lexical_block) <3><405>: Abbrev Number: 21 (DW_TAG_variable) <406> DW_AT_name : st ... But in the Go case, that scoping is missing: ... <1><155>: Abbrev Number: 10 (DW_TAG_variable) <156> DW_AT_name : main.st (DW_OP_addr: 60e1f0) <1><1ceb>: Abbrev Number: 34 (DW_TAG_subprogram) <1cec> DW_AT_name : main.main <2><1d05>: Abbrev Number: 35 (DW_TAG_variable) <1d06> DW_AT_name : st ...