我有一些 go-code (myclient)。它看起来像这样(这里只有 mypackage 是相关的):
package mypackage
import (
...
func (o *Client) CreateUser(ctx context.Context, user *User, ...) (User, error) {
...
if err != nil ...
return nil, err
...
return &user, nil
}
我运行 go build -o build/myclient cmd/myclient/main.go
来获取二进制文件。
λ bob [~] → objdump -t ~/go/src/github.com/Corp/myclient/build/myclient | grep CreateUser
....
000000000087d490 l F .text 0000000000000e55 github.com/Corp/myclient.(*Client).CreateUser
现在这个二进制文件被其他一些 go 程序使用并被加载。
有点像这样:
bob 745322 0.1 0.1 195556 33172 pts/1 Sl+ 20:18 0:07 some-prog
bob 750774 0.0 0.0 1229316 14188 pts/1 Sl+ 20:22 0:00 /home/bob/go/src/github.com/Corp/myclient/build/myclient
现在我尝试使用密件抄送工具进行跟踪/调试。这样做的原因是在生产中发生了一些奇怪的错误,查看上面函数的参数和返回值很重要。我的灵感来自于此:http://www.brendangregg.com/blog/2017-01-31/golang-bcc-bpf-function-tracing.html
当使用 funccount
时,我在这里看到了这个(在通过调用 some-prog 调用函数之后)
λ bob [~] → sudo funccount '/home/bob/go/src/github.com/Corp/myclient/build/myclient:*.CreateUser'
Tracing 5 functions for "b'/home/bob/go/src/github.com/Corp/myclient/build/myclient:*.CreateUser'"... Hit Ctrl-C to end.
^C
FUNC COUNT
...
b'github.com/Corp/myclient.(*Client).CreateUser' 1
Detaching...
但是当我尝试使用 trace
(或 gotrace
)时,它看起来像这样:
λ bob [~] → trace '/home/bob/go/src/github.com/Corp/myclient/build/myclient:mypackage.*'
could not determine address of symbol b'mypackage.*'
λ bob [~] → trace '/home/bob/go/src/github.com/Corp/myclient/build/myclient:github.com/Corp/myclient.CreateUser'
could not determine address of symbol b'github.com/Corp/myclient.CreateUser'
λ bob [~] → trace '/home/bob/go/src/github.com/Corp/myclient/build/myclient:github.com/Corp/myclient.(*Client).CreateUser'
error in probe '/home/bob/go/src/github.com/Corp/myclient/build/myclient:github.com/Corp/myclient.(*Client).CreateUser': expected format string in "s
λ bob [~] → trace '/home/bob/go/src/github.com/Corp/myclient/build/myclient:*.CreateUser'
could not determine address of symbol b'*.CreateUser'
是否有可能使用 BCC 工具或 eBPF/(bpftrace?)(不添加任何代码)跟踪这样的 go-function(特别是检查结构参数和返回值)
最佳答案
trace是一个python脚本,你可以在vim中打开它,然后搜索一个名为_parse_probe的函数。在此函数中,第 96 行:
(spec, sig, rest) = re.match(r'([^ \t\(]+)(\([^\(]*\))?(.*)', text).groups()
带有'('字符的golang函数符号被分成3部分,而普通函数将匹配第一个正则子字符串。您可以修改正则表达式——删除'('部分,然后跟踪将起作用。祝你好运。
关于debugging - 如何使用 BPF (BCC) 跟踪 go 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59165266/