A simple Go program, say main.go
:
package main
func main() {
println("hello, world!")
}
Then build with
go build -gcflags "-N -l" -o main main.go
Using GDB:
$ gdb main
GNU gdb (GDB) 8.2
(...)
Reading symbols from main...(no debugging symbols found)...done.
Loading Go Runtime support.
(gdb) source /usr/local/Cellar/go/1.11/libexec/src/runtime/runtime-gdb.py
Loading Go Runtime support.
(gdb) info files
Symbols from "/Users/changkun/Desktop/demo/main".
Local exec file:
`/Users/changkun/Desktop/demo/main', file type mach-o-x86-64.
Entry point: 0x1049e20
0x0000000001001000 - 0x000000000104dfcf is .text
0x000000000104dfe0 - 0x0000000001077344 is __TEXT.__rodata
(...)
(gdb) b *0x1049e20
Breakpoint 1 at 0x1049e20
(gdb)
There is no at
in the GDB outputs, the version of Go is go version go1.11 darwin/amd64
and:
$ ls -al /usr/local/bin | grep go
lrwxr-xr-x 1 changkun admin 24 Aug 25 16:37 go -> ../Cellar/go/1.11/bin/go
======
Same process in linux environment:
docker run -itd --name golang golang:1.11
docker exec -it golang bash
then entering container install gdb
root@1326d3f1a957:/# gdb main
GNU gdb (Debian 7.12-6) 7.12.0.20161007-git
(...)
(gdb) info files
Symbols from "/main".
Local exec file:
`/main', file type elf64-x86-64.
Entry point: 0x44a2e0
0x0000000000401000 - 0x000000000044ea8f is .text
(...)
(gdb) b *0x44a2e0
Breakpoint 1 at 0x44a2e0: file /usr/local/go/src/runtime/rt0_linux_amd64.s, line 8.
(gdb)
Linux is able to show (gdb) b *0x44a2e0 Breakpoint 1 at 0x44a2e0: file /usr/local/go/src/runtime/rt0_linux_amd64.s, line 8.
What did I miss in macOS? How can I debug and trace the program on macOS?
In Go 1.11, the debug information is compressed for purpose of reduce binary size, and gdb on the Mac does not understand compressed DWARF.
The workaround is to also specify -ldflags=-compressdwarf=false
which does exactly what it claims.
To do this generally:
export GOFLAGS="-ldflags=-compressdwarf=false"
See discussion: https://groups.google.com/forum/#!topic/golang-nuts/LlgN1qpbRE8