SimonKagstrom / kcov

Code coverage tool for compiled programs, Python and Bash which uses debugging information to collect and report data without special compilation options
http://simonkagstrom.github.io/kcov/
GNU General Public License v2.0
710 stars 109 forks source link

Does the lldb engine support go binary? #400

Closed myzhan closed 1 year ago

myzhan commented 1 year ago

I'm tring to use kcov against go binary, but module.GetNumCompileUnits returns zero, so I can't get the file:line -> address mapping.

SimonKagstrom commented 1 year ago

I'm not sure how go works, but it sounds like there's no debug info in the binary? Unless go uses some non-standard way of storing the debug info.

Message ID: @.***>

Can you debug the binary with lldb?

myzhan commented 1 year ago

Can't debug the binary with lldb.

Here is the procedure to reproduce.

package main

func main() {
        println("Hello world")
}
$ go version
go version go1.20.4 darwin/amd64
$ lldb --version
lldb-1403.0.17.67
Apple Swift version 5.8.1 (swiftlang-5.8.0.124.5 clang-1403.0.22.11.100)
$ go build -o hello hello.go

The ./hello binary can be debug with dlv, but not lldb.

$ dlv exec ./hello
Type 'help' for list of commands.
(dlv) b main.main
Breakpoint 1 set at 0x1057146 for main.main() ./hello.go:3
(dlv)
$ lldb ./hello
(lldb) target create "./hello"
Current executable set to '/Users/zhanqp/github/goc/cmd/hello' (x86_64).
(lldb) b main.main
Breakpoint 1: no locations (pending).
WARNING:  Unable to resolve breakpoint to any actual locations.
SimonKagstrom commented 1 year ago

I found this page about go and gdb, https://go.dev/doc/gdb, perhaps some hints there?

myzhan commented 1 year ago

No luck, tried to build with '-N -l'.

myzhan commented 1 year ago

FYI, I try it on ubuntu, and it works. Maybe there are issues of my lldb installation on my macos.

myzhan commented 1 year ago

Finally, I make it work. The default lldb installation doesn't support the compressed dwarf sections, so I can build go binary without compressing them.

go build -ldflags=-compressdwarf=false -o hello ./hello.go
myzhan commented 1 year ago

It took a lot of time to run the simple helloworld above.


$ export GODEBUG=asyncpreemptoff=1
$ time /Users/zhanqp/github/kcov/build/src/Release/kcov ./output ./hello
warning: failed to set breakpoint site at 0x7ff8002bd6a1 for breakpoint 1.1: error: 9 sending the breakpoint request
warning: This version of LLDB has no plugin for the language "go". Inspection of frame variables will be limited.
Hello world
/Users/zhanqp/github/kcov/build/src/Release/kcov ./output ./hello  102.32s user 116.79s system 89% cpu 4:05.11 total
SimonKagstrom commented 1 year ago

Yes, unfortunately the lldb-engine is very slow (magnitudes slower than Linux...). I've done some work on writing a "native" implementation of a Mac OS "engine", but I've only managed to replace the Mach-O parsing so far. OSX doesn't use ptrace the same way as Linux/BSD, so writing a debugger in it is quite a bit different than I'm used to.

myzhan commented 1 year ago

I aslo tried to write a toy project like this, and it's hard for me. Because of the lack of ptrace capabilities and documentations. I'm reading the source code of delve for help.

SimonKagstrom commented 1 year ago

Indeed! I've pushed my hacks so far on the macho-parser branch if you'd like too help! I'm currently (as free time allows...) hacking in src/engines/mach_ports.c, which is based on various sources found by googling and allows starting and attaching to a process.

SimonKagstrom commented 1 year ago

I now have a working version (at least for more limited uses) of the "native" version in the mach-parser branch. It's still much slower than Linux/FreeBSD, but should be at least 15 times faster than the lldb version (got tired of waiting for the old test so stopped it :-)).

myzhan commented 1 year ago

OK, I'll find some time to test it.

SimonKagstrom commented 1 year ago

Forgot to say: it's x86-only for now