Как отследить функцию go с помощью BPF (BCC)

У меня есть код перехода (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

Теперь я пытаюсь использовать BCC Tools для трассировки/отладки. Причина этого в том, что в продакшне случаются странные ошибки, и важно просматривать аргументы и возвращаемые значения функции выше. Меня вдохновило это: http://www.brendangregg.com/blog/2017-01-31/golang-bcc-bpf-function-tracing.html

При использовании funccount вижу вот это (после вызова функции каким-то вызовом какой-то проги)

λ 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'

Есть ли возможность отследить такую ​​функцию go (особенно проверку аргументов структуры и возвращаемого значения) с помощью инструментов BCC или eBPF/(bpftrace?) (без добавления кода)


person x4k3p    schedule 03.12.2019    source источник


Ответы (1)


trace — это скрипт на Python, вы можете открыть его в vim, а затем найти функцию с именем _parse_probe. В этой функции строка 96:

(spec, sig, rest) = re.match(r'([^ \t\(]+)(\([^\(]*\))?(.*)', text).groups()                                    

Символ функции golang с символом '(' разбивается на 3 части, тогда как обычная функция будет соответствовать первой регулярной подстроке. Вы можете изменить регулярное выражение — удалить часть '(', и тогда трассировка будет работать. Удачи.

person vcinq    schedule 10.01.2020