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

runtime: TestGdbPythonCgo fails with the gold linker #26868

Closed
mvdan opened this issue Aug 8, 2018 · 9 comments

Comments

Projects
None yet
4 participants
@mvdan
Copy link
Member

commented Aug 8, 2018

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

go version devel +9ef5ee911c Tue Aug 7 14:36:14 2018 +0000 linux/amd64

Does this issue reproduce with the latest release?

No - all seems fine on Go 1.10.3. Hence this is a potential regression.

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

GOARCH="amd64"
GOBIN=""
GOCACHE="/home/mvdan/go/cache"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/mvdan/go/land:/home/mvdan/go"
GOPROXY=""
GORACE=""
GOROOT="/home/mvdan/tip"
GOTMPDIR=""
GOTOOLDIR="/home/mvdan/tip/pkg/tool/linux_amd64"
GCCGO="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-build726868981=/tmp/go-build -gno-record-gcc-switches"

What did you do?

go test runtime

What did you expect to see?

A PASS.

What did you see instead?

--- FAIL: TestGdbPythonCgo (0.84s)
    runtime-gdb_test.go:64: gdb version 8.1
    runtime-gdb_test.go:198: gdb output: No auto-load scripts.

I investigated for a while, and I think I know the reason for the failure. Please keep in mind that my understanding of gdb and ELF binaries is limited, so I might be wrong.

I first noted that adding a line to the test to manually load runtime-gdb.py made the test pass, so it seemed like the file wasn't being automatically loaded:

"-ex", "source " + filepath.Join(runtime.GOROOT(), "src", "runtime", "runtime-gdb.py"),

Then, from reading the python file:

This script is loaded by GDB when it finds a .debug_gdb_scripts
section in the compiled binary. The [68]l linkers emit this with a
path to this file based on the path to the runtime package.

Note that TestGdbPythonCgo fails, but TestGdbPython succeeds. So I wondered if a cgo binary was missing this section. On Go 1.10, both binaries have the section:

$ go1 version
go version go1.10.3 linux/amd64
$ cat ~/main.go
package main

func main() {
}
$ go1 build ~/main.go
$ objdump -s -j .debug_gdb_scripts main

main:     file format elf64-x86-64

Contents of section .debug_gdb_scripts:
 4e2960 012f7573 722f6c69 622f676f 2f737263  ./usr/lib/go/src
 4e2970 2f72756e 74696d65 2f72756e 74696d65  /runtime/runtime
 4e2980 2d676462 2e707900                    -gdb.py.
$ cat ~/main-cgo.go
package main

import "C"

func main() {
}
$ go1 build ~/main-cgo.go
$ objdump -s -j .debug_gdb_scripts main-cgo

main-cgo:     file format elf64-x86-64

Contents of section .debug_gdb_scripts:
 0000 012f7573 722f6c69 622f676f 2f737263  ./usr/lib/go/src
 0010 2f72756e 74696d65 2f72756e 74696d65  /runtime/runtime
 0020 2d676462 2e707900                    -gdb.py.

However, on master, the cgo binary is lacking the section:

$ go build ~/main.go
$ objdump -s -j .debug_gdb_scripts main

main:     file format elf64-x86-64

Contents of section .debug_gdb_scripts:
 4ebe9e 012f686f 6d652f6d 7664616e 2f746970  ./home/mvdan/tip
 4ebeae 2f737263 2f72756e 74696d65 2f72756e  /src/runtime/run
 4ebebe 74696d65 2d676462 2e707900           time-gdb.py.
$ go build ~/main-cgo.go
$ objdump -s -j .debug_gdb_scripts main-cgo

main-cgo:     file format elf64-x86-64

objdump: section '.debug_gdb_scripts' mentioned in a -j option, but not found in any input file

Am I missing something obvious here, or misunderstanding how all this works?

@ianlancetaylor any help or pointers appreciated. Since this is very likely a linker fix, I'll leave the CL (if any) to someone else.

@mvdan mvdan added this to the Go1.11 milestone Aug 8, 2018

@mvdan

This comment has been minimized.

Copy link
Member Author

commented Aug 8, 2018

I had forgotten to include the main-cgo.go contents - updated.

@heschik heschik self-assigned this Aug 8, 2018

@heschik

This comment has been minimized.

Copy link
Contributor

commented Aug 8, 2018

It doesn't make sense to me, but I guess the scripts section is getting compressed. Does .zdebug_gdb_scripts exist?

If so that's surprising, since the linker won't compress a section unless it gets smaller, and I've never seen the script path be compressible enough. But maybe your home directory path is the first.

If GDB doesn't decompress this it's simple enough to keep it uncompressed.

@mvdan

This comment has been minimized.

Copy link
Member Author

commented Aug 8, 2018

@heschik you're right - on Go master, main has .debug_gdb_scripts, and main-cgo has .zdebug_gdb_scripts. It seems to me like the data is still bigger, though:

$ objdump -s -j .zdebug_gdb_scripts main-cgo
main-cgo:     file format elf64-x86-64

Contents of section .zdebug_gdb_scripts:
 0000 5a4c4942 00000000 0000002c 780163d4  ZLIB.......,x.c.
 0010 cfc8cf4d d5cf2d4b 49ccd32f c92cd02f  ...M..-KI../.,./
 0020 2e4ad62f 2acd2bc9 048a4269 ddf49424  .J./*.+...Bi...$
 0030 bd824a06 0062d00f e9                 ..J..b...
$ objdump -s -j .debug_gdb_scripts main
main:     file format elf64-x86-64

Contents of section .debug_gdb_scripts:
 4ebe9e 012f686f 6d652f6d 7664616e 2f746970  ./home/mvdan/tip
 4ebeae 2f737263 2f72756e 74696d65 2f72756e  /src/runtime/run
 4ebebe 74696d65 2d676462 2e707900           time-gdb.py.
@heschik

This comment has been minimized.

Copy link
Contributor

commented Aug 8, 2018

Oh, right, cgo, so external linker, so it's gcc/ld that's doing the compression. I think this is a bug/misfeature in the version of ld you're using. My version of ld (2.30, possibly with patches) doesn't compress .debug_gdb_scripts. What are you using?

I can't think of any workaround for this other than figuring out which versions of ld behave this way and not passing --compress-debug-sections to them. We could ask for gdb to understand it. But really I'd expect most people to be using Delve at this point.

@mvdan

This comment has been minimized.

Copy link
Member Author

commented Aug 8, 2018

I see. I simply raised this issue as there was a runtime test not passing. Perhaps the test can be skipped if people are using the same linker that I am, to avoid the failures we can't really fix.

$ ld --version
GNU gold (GNU Binutils 2.31.1) 1.16
@heschik

This comment has been minimized.

Copy link
Contributor

commented Aug 8, 2018

@ianlancetaylor -- should we check for gold in this test and skip?

@ianlancetaylor

This comment has been minimized.

Copy link
Contributor

commented Aug 8, 2018

It sounds like a bug that gold might compress that section. Filed https://sourceware.org/bugzilla/show_bug.cgi?id=23495 .

For test purposes can we just check for an uncompress .debug_gdb_scripts section?

@mvdan mvdan changed the title cmd/link: importing "C" makes the .debug_gdb_scripts section disappear runtime: TestGdbPythonCgo fails with the gold linker Aug 8, 2018

@mvdan

This comment has been minimized.

Copy link
Member Author

commented Aug 8, 2018

Thanks Ian, that makes sense. I've retitled the bug.

I have a temporary fix stashed on git which should do the job on the cgo test - using source on the gdb python script directly. I can submit that once I'm back on the laptop if it seems fine.

@gopherbot

This comment has been minimized.

Copy link

commented Aug 9, 2018

Change https://golang.org/cl/128815 mentions this issue: runtime: fix TestGdbPythonCgo failure with ld.gold

@gopherbot gopherbot closed this in a0127c1 Aug 9, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.