Description
What version of Go are you using (go version
)?
$ go version go version go1.13.3 linux/amd64
What operating system and processor architecture are you using (go env
)?
go env
Output
$ go env GO111MODULE="" GOARCH="amd64" GOBIN="" GOCACHE="/root/.cache/go-build" GOENV="/root/.config/go/env" GOEXE="" GOFLAGS="" GOHOSTARCH="amd64" GOHOSTOS="linux" GONOPROXY="" GONOSUMDB="" GOOS="linux" GOPATH="/root/py3/Project/GOPATH" GOPRIVATE="" GOPROXY="https://proxy.golang.org,direct" GOROOT="/root/py3/Project/go" GOSUMDB="sum.golang.org" GOTMPDIR="" GOTOOLDIR="/root/py3/Project/go/pkg/tool/linux_amd64" GCCGO="gccgo" AR="ar" 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-build442453090=/tmp/go-build -gno-record-gcc-switches"
What did you do?
A simple demo
package main
import (
"fmt"
"os"
"time"
)
var a = 0
//go:noinline
func TestFunc() {
a++
time.Sleep(time.Millisecond * 100)
}
func main() {
fmt.Println(os.Getpid())
for i := 0; i < 100000; i++ {
TestFunc()
}
}
go install -buildmode=shared -linkshared std
go build -linkshared main.go
./main
Then I use gdb
to debug, when I use s
for single step debugging, it will appear:
which has no line number information.
gdb attach 3839
What did you expect to see?
Can be debugged step by step.
What did you see instead?
Type "apropos word" to search for commands related to "word"...
attach: No such file or directory.
Attaching to process 3839
[New LWP 3840]
[New LWP 3841]
[New LWP 3842]
[New LWP 3843]
[New LWP 3844]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
0x00007fb989b424b3 in runtime.futex ()
from /root/py3/Project/go/pkg/linux_amd64_dynlink/libstd.so
(gdb) b main.TestFunc
Breakpoint 1 at 0x55563d1f77a0
(gdb) c
Continuing.
Thread 1 "main" hit Breakpoint 1, 0x000055563d1f77a0 in main.TestFunc ()
(gdb) s
Single stepping until exit from function main.TestFunc,
which has no line number information.
Thread 1 "main" hit Breakpoint 1, 0x000055563d1f77a0 in main.TestFunc ()
(gdb) s
Single stepping until exit from function main.TestFunc,
which has no line number information.
0x00007fb989b2c680 in time.Sleep ()
from /root/py3/Project/go/pkg/linux_amd64_dynlink/libstd.so
Even if I use go build -gcflags = '-N -l' -linkshared main.go
, still get the same error.
When I use the static link go build main.go
, it can be stepped normally.
The process of my analysis:
Add -x
option to re-compile, it can be seen that when ld
is called, -w
is added
root/py3/Project/go/pkg/tool/linux_amd64/link -o $WORK/b001/exe/a.out -importcfg $WORK/b001/importcfg.link -installsuffix dynlink -buildmode=exe -buildid=0NYYkm8PmmuyphRyKmYC/4b2T8RfBMeRtkph2OZPF/9y-yYjcMEG_-re1WmH11/0NYYkm8PmmuyphRyKmYC -linkshared -w -extld=gcc /root/.cache/go-build/9d/9d922fc73643e08291edcd472d78431a941d02ea4a67c48a58d6e240635f2934-d
/root/py3/Project/go/pkg/tool/linux_amd64/buildid -w $WORK/b001/exe/a.out # internal
In the source code, if the -w
option is added, the .debug_line
information will not be generated
func dwarfGenerateDebugSyms(ctxt *Link) {
if !dwarfEnabled(ctxt) {
return
}
……
// Write per-package line and range tables and start their CU DIEs.
debugLine := ctxt.Syms.Lookup(".debug_line", 0)
debugLine.Type = sym.SDWARFSECT
debugRanges := ctxt.Syms.Lookup(".debug_ranges", 0)
debugRanges.Type = sym.SDWARFRANGE
debugRanges.Attr |= sym.AttrReachable
syms = append(syms, debugLine)
……
}
I guess -w
was added here, and there is a legacy TODO
func buildModeInit() {
gccgo := cfg.BuildToolchainName == "gccgo"
……
if cfg.BuildLinkshared {
if gccgo {
codegenArg = "-fPIC"
} else {
switch platform {
case "linux/386", "linux/amd64", "linux/arm", "linux/arm64", "linux/ppc64le", "linux/s390x":
forcedAsmflags = append(forcedAsmflags, "-D=GOBUILDMODE_shared=1")
default:
base.Fatalf("-linkshared not supported on %s\n", platform)
}
codegenArg = "-dynlink"
// TODO(mwhudson): remove -w when that gets fixed in linker.
forcedLdflags = append(forcedLdflags, "-linkshared", "-w")
}
}
}
I want to ask, for dynamically compiled programs, cannot use gdb
for single-step debugging, Is there any consideration or any bug
?
Is there a supporting plan for this?
This scene is very important to me, I am looking forward to receiving your reply, thank you.