英文:
No symbol in binary after "go build"
问题
我正在遵循这篇文章来理解eBPF跟踪的工作原理,其中的第一步是识别函数的符号,示例代码可以从这里获取:https://github.com/pixie-labs/pixie-demos/blob/main/simple-gotracing/app/app.go
然而,在构建之后,我无法找到该符号。为什么会这样?
$ ls
go.mod main.go
$ grep func main.go
func computeE(iterations int64) float64 {
func main() {
http.HandleFunc("/e", func(w http.ResponseWriter, r *http.Request) {
$ go build
$ objdump --syms ./demowebservice | grep compute
0000000000840a40 g O .bss 0000000000000008 crypto/elliptic.p256Precomputed
00000000008704c0 g O .noptrbss 000000000000000c crypto/elliptic.precomputeOnce
$
Go版本:-
$ go version
go version go1.16.5 linux/amd64
英文:
I'm following this article to understand how eBPF tracing works, one of the first steps is to identify the symbol for the function, example code is picked up from here: https://github.com/pixie-labs/pixie-demos/blob/main/simple-gotracing/app/app.go
However, after doing the build, I'm unable to find the symbol. Why is that the case?
$ ls
go.mod main.go
$ grep func main.go
func computeE(iterations int64) float64 {
func main() {
http.HandleFunc("/e", func(w http.ResponseWriter, r *http.Request) {
$ go build
$ objdump --syms ./demowebservice | grep compute
0000000000840a40 g O .bss 0000000000000008 crypto/elliptic.p256Precomputed
00000000008704c0 g O .noptrbss 000000000000000c crypto/elliptic.precomputeOnce
$
Go version:-
$ go version
go version go1.16.5 linux/amd64
答案1
得分: 6
您的computeE()
函数将被内联,因此函数名在可执行二进制文件中不会留下"标记"。您可以使用go build -gcflags=-m
命令查看在构建过程中哪些函数被"内联"。
如果禁用内联:
//go:noinline
func computeE(iterations int64) float64 {
// ...
}
然后再次构建和检查:
$ go build -gcflags=-m |& grep inlining
./main.go:24:17: inlining call to http.HandleFunc
./main.go:24:17: inlining call to http.(*ServeMux).HandleFunc
./main.go:43:12: inlining call to fmt.Printf
./main.go:44:28: inlining call to http.ListenAndServe
./main.go:46:13: inlining call to fmt.Printf
$ objdump --syms ./demowebservice | grep compute
输出将类似于:
000000000062a940 g F .text 000000000000004c main.computeE
0000000000840a40 g O .bss 0000000000000008 crypto/elliptic.p256Precomputed
00000000008704c0 g O .noptrbss 000000000000000c crypto/elliptic.precomputeOnce
相关链接:https://stackoverflow.com/questions/68280753/forbid-inlining-in-golang/68280986#68280986
英文:
Your computeE()
function will be inlined and thus the function name will leave no "marks" in the executable binary. You can use go build -gcflags=-m
to see what functions are being inlined
in the build process.
$ go build -gcflags=-m |& grep inlining
./main.go:24:17: inlining call to http.HandleFunc
./main.go:24:17: inlining call to http.(*ServeMux).HandleFunc
./main.go:43:12: inlining call to fmt.Printf
./main.go:44:28: inlining call to http.ListenAndServe
./main.go:46:13: inlining call to fmt.Printf
./main.go:40:53: inlining call to computeE <-- NOTE THIS
If you disable inlining:
//go:noinline
func computeE(iterations int64) float64 {
// ...
}
And then build and check again:
$ go build -gcflags=-m |& grep inlining
./main.go:24:17: inlining call to http.HandleFunc
./main.go:24:17: inlining call to http.(*ServeMux).HandleFunc
./main.go:43:12: inlining call to fmt.Printf
./main.go:44:28: inlining call to http.ListenAndServe
./main.go:46:13: inlining call to fmt.Printf
$ objdump --syms ./demowebservice | grep compute
Then output will be something like this:
000000000062a940 g F .text 000000000000004c main.computeE
0000000000840a40 g O .bss 0000000000000008 crypto/elliptic.p256Precomputed
00000000008704c0 g O .noptrbss 000000000000000c crypto/elliptic.precomputeOnce
See related: https://stackoverflow.com/questions/68280753/forbid-inlining-in-golang/68280986#68280986
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论