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

Open
aclements opened this issue Nov 5, 2018 · 7 comments
Open

cmd/compile: can't break on inlined function #28603

aclements opened this issue Nov 5, 2018 · 7 comments

Comments

@aclements
Copy link
Member

@aclements 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
Copy link
Member

@thanm 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
Copy link
Contributor

@randall77 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
Copy link
Member

@thanm 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
Copy link
Contributor

@randall77 randall77 commented Nov 5, 2018

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

@randall77
Copy link
Contributor

@randall77 randall77 commented May 16, 2019

Note that although you can't break at the name, you can break at the line number.

@gopherbot
Copy link

@gopherbot gopherbot commented May 16, 2019

Change https://golang.org/cl/177697 mentions this issue: cmd/compile: mention issue 28603 when discussing where inline marks go

gopherbot pushed a commit that referenced this issue May 17, 2019
Update #28603

Change-Id: I8bdbea57b3661e15dcc760d27252b794daa476db
Reviewed-on: https://go-review.googlesource.com/c/go/+/177697
Reviewed-by: Emmanuel Odeke <emm.odeke@gmail.com>
@andybons andybons modified the milestones: Go1.13, Go1.14 Jul 8, 2019
@thanm
Copy link
Member

@thanm thanm commented Sep 11, 2019

Duplicate of #26206

@thanm thanm marked this as a duplicate of #26206 Sep 11, 2019
@thanm thanm modified the milestones: Go1.14, Unplanned Sep 17, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
5 participants
You can’t perform that action at this time.