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: can't break on inlined function #28603

Open
aclements opened this Issue Nov 5, 2018 · 4 comments

Comments

Projects
None yet
3 participants
@aclements
Member

aclements commented Nov 5, 2018

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

$ go version
go version devel +e72595ee0f Mon Nov 5 19:10:33 2018 +0000 linux/amd64

(latest master)

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"
GOBIN=""
GOCACHE="/home/austin/.cache/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/austin/r/go"
GOPROXY=""
GORACE=""
GOROOT="/home/austin/go.dev"
GOTMPDIR=""
GOTOOLDIR="/home/austin/go.dev/pkg/tool/linux_amd64"
GCCGO="/usr/bin/gccgo"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build704555549=/tmp/go-build -gno-record-gcc-switches"

What did you do?

Attempt to set a breakpoint on an inlined function.

E.g., paste https://play.golang.org/p/rDXmoTUZKJb in to bp.go and run

go build bp.go
gdb ./bp
(gdb) br 'main.f'
Function "main.f" not defined.
(gdb) br 'main.main'
Breakpoint 1 at 0x455660: file /home/austin/go.dev/austin/bp.go, line 5.

What did you expect to see?

I expected to be able to set a breakpoint on main.f like I could on main.main. In C/C++, this would cause gdb to set a breakpoint on every location the function was inlined to.

What did you see instead?

main.f is completely missing from the debug info, so GDB is unable to set the breakpoint.

/cc @randall77 @thanm

@aclements aclements added this to the Go1.13 milestone Nov 5, 2018

@thanm

This comment has been minimized.

Member

thanm commented Nov 5, 2018

From my experience working with C compilers, one sees the same thing there when optimization is enabled. For example with this program:

#include <stdlib.h>
static int f() {
  return 42;
}
int main(int argc, char **argv) {
  exit(f());
}

if I compile with tip clang, there is no trace of "f" left in the DWARF. GCC does slightly better in that it generates a subprogram DIE for "f", but since there are no longer any instructions from "f", you can't set a breakpoint on it.

At the moment the Go compiler is doing the same thing-- if there aren't any remaining instructions (defined in some loose sense) from the original inlined routine, it is not going to turn up in the DWARF.

@randall77

This comment has been minimized.

Contributor

randall77 commented Nov 5, 2018

As far as I can tell, inlined functions that have instructions that end up in the binary, still don't work. For Go:

package main

var x int = 1

func main() {
	x = f(x)
	println(x)
}

func f(x int) int {
	return x << 8
}

and C

#include <stdlib.h>

static int f(int x) {
  return x << 8;
}

int g = 1;

int main(int argc, char **argv) {
  exit(f(g));
}

There's a shl $8 instruction in both binaries, but I can't break f in gdb on either of them.

@thanm

This comment has been minimized.

Member

thanm commented Nov 5, 2018

I tried the shift example with tip GCC and GDB 7.x and it works for me:

$ /w/gcc-trunk/build-gcc/.../gcc -O -g inlshift8.c
$ /w/binutils-trunk/install-7.12/bin/gdb a.out
GNU gdb (GDB) 7.12.1.20170417-git
...
Reading symbols from a.out...done.
(gdb) b f
Breakpoint 1 at 0x400556: file inlshift8.c, line 10.
(gdb) run
Starting program: /usr/local/google/home/thanm/a.out 
Breakpoint 1, main (argc=1, argv=0x7fffffffdcd8) at inlshift8.c:10
10	  exit(f(g));
(gdb) si
0x000000000040055c in f (x=<optimized out>) at inlshift8.c:10
10	  exit(f(g));
(gdb) where
#0  0x000000000040055c in f (x=<optimized out>) at inlshift8.c:10
#1  main (argc=<optimized out>, argv=0x7fffffffdcd8) at inlshift8.c:10
(gdb) 

This is obviously not very helpful to you, however. With this sort of debug info generation (e.g. with other optimizations turned on) it's a very "best effort only" scenario. If things get optimized "too much" (whatever that is) then the DWARF disappears or gets degraded.

@randall77

This comment has been minimized.

Contributor

randall77 commented Nov 5, 2018

Ah, I forgot the -g. The C example now works for me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment