Golang:什么是etext?

10

我已经开始对我的Go1.2代码进行分析,而排在最前面的项目总是名为“etext”的东西。我已经搜索了很多资料,但除了它可能与Go例程中的调用深度有关之外,并没有找到太多信息。但是,我并没有使用任何Go例程,“etext”仍然占据了总执行时间的75%或更多。

(pprof) top20 
Total: 171 samples
    128  74.9%  74.9%      128  74.9% etext

有人能解释一下这是什么,是否有任何方法来减少影响吗?


这似乎很相关:https://groups.google.com/d/topic/golang-nuts/KEkZ0-t4Bu0/discussion 显然这与OSX中的一个错误有关。 - Tyler
2
是的,我找到了这两个,但我正在Linux上进行分析,所以第一篇文章不适用于我,而且我没有使用函数文字或大量递归,所以我看不出第二篇文章如何适用。 - Bill
etext是标记文本段结束的符号。这对我来说看起来像个错误。你的代码中是否动态加载库? - fuz
不,这很简单,Go 语言。 - Bill
1
虽然etext超出了正常的文本段,但共享库映射在其之外,因此它可能是一个没有符号的共享库(例如,在Debian上,您必须专门安装-dbg软件包)。或者它可能是一个跳板调用,即在运行时构建的短代码片段。 - Matthias Urlichs
显示剩余4条评论
2个回答

3

我曾遇到同样的问题,后来发现了这篇文章:go1.2版本的pprof出现问题?。为了验证是否真的是1.2版本的bug,我编写了以下的“hello world”程序:

package main

import (
    "fmt"
    "testing"
)

func BenchmarkPrintln( t *testing.B ){
    TestPrintln( nil )
}

func TestPrintln( t *testing.T ){
    for i := 0; i < 10000; i++ {
            fmt.Println("hello " + " world!")
    }
}

正如您所看到的,它只调用了fmt.Println函数。

您可以使用“go test -c”编译它。 使用“./test.test -test.bench . -test.cpuprofile=test.prof”运行。 使用“go tool pprof test.test test.prof”查看结果。

(pprof) top10
Total: 36 samples
  18  50.0%  50.0%       18  50.0% syscall.Syscall
   8  22.2%  72.2%        8  22.2% etext
   4  11.1%  83.3%        4  11.1% runtime.usleep
   3   8.3%  91.7%        3   8.3% runtime.futex
   1   2.8%  94.4%        1   2.8% MHeap_AllocLocked
   1   2.8%  97.2%        1   2.8% fmt.(*fmt).padString
   1   2.8% 100.0%        1   2.8% os.epipecheck
   0   0.0% 100.0%        1   2.8% MCentral_Grow
   0   0.0% 100.0%       33  91.7% System
   0   0.0% 100.0%        3   8.3% _/home/xxiao/work/test.BenchmarkPrintln

以上结果是使用go 1.2.1得到的。 然后我使用go 1.1.1做同样的事情,得到了以下结果:

(pprof) top10
Total: 10 samples
   2  20.0%  20.0%        2  20.0% scanblock
   1  10.0%  30.0%        1  10.0% fmt.(*pp).free
   1  10.0%  40.0%        1  10.0% fmt.(*pp).printField
   1  10.0%  50.0%        2  20.0% fmt.newPrinter
   1  10.0%  60.0%        2  20.0% os.(*File).Write
   1  10.0%  70.0%        1  10.0% runtime.MCache_Alloc
   1  10.0%  80.0%        1  10.0% runtime.exitsyscall
   1  10.0%  90.0%        1  10.0% sweepspan
   1  10.0% 100.0%        1  10.0% sync.(*Mutex).Lock
   0   0.0% 100.0%        6  60.0% _/home/xxiao/work/test.BenchmarkPrintln

你可以看到,1.2.1的结果并没有太多意义。Syscall和etext占用了大部分时间。而1.1.1的结果看起来是正确的。
所以我相信这确实是一个1.2.1的bug。我已经在我的真实项目中切换到使用go 1.1.1,并且现在对剖析结果感到满意。

这看起来像是正确的答案。在我的测试中看到了类似的结果。 - Bill

2
我认为Mathias Urlichs在关于您的cgo代码中缺少调试符号方面是正确的。值得注意的是,一些标准包(如net和syscall)使用了cgo。
如果您滚动到此doc底部的Caveats部分,您可以看到第三个项目说...
“如果程序链接到一个没有足够符号信息编译的库,则可能会将与该库相关的所有样本计入程序前找到的最后一个符号。这将人为地增加该符号的计数。”
我不是100%确定这是否是发生的情况,但我敢打赌这就是为什么etext看起来很忙碌的原因(换句话说,etext是各种函数的集合,没有足够的信息供pprof进行适当的分析)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接