[Bug go/93844] New: [debug] Incorrect scope for local variables

vries at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Thu Feb 20 07:50:00 GMT 2020


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
...


More information about the Gcc-bugs mailing list