英文:
index out of range error when profiling go program
问题
这篇博文提供了使用runtime/pprof
包对golang程序进行性能分析的说明。
除了上述提到的包导入之外,它说(步骤1)要将以下代码添加到main函数中:
var cpuprofile = flag.String("cpuprofile", "", "write cpu profile to file")
func main() {
flag.Parse()
if *cpuprofile != "" {
f, err := os.Create(*cpuprofile)
if err != nil {
log.Fatal(err)
}
pprof.StartCPUProfile(f)
defer pprof.StopCPUProfile()
}
}
然后(步骤2)运行二进制文件(在本例中命名为./havlak1),并将带有扩展名为.prof的文件名传递给cpuprofile标志:
./havlak1 -cpuprofile=havlak1.prof
然后,在程序停止后,(步骤3)将二进制文件和.prof
文件传递给go tool pprof
程序:
$ go tool pprof havlak1 havlak1.prof
Welcome to pprof! For help, type 'help'.
(pprof)
此时,博文作者运行top10
命令以获取一些输出。
我已经按照这些步骤对我的程序进行了操作(但使用了不同的二进制文件和.prof文件名)。然而,当我运行top10
命令时,我的程序会出现索引越界错误。如果我运行以下命令来检查.prof
文件的内容:
cat myfile.prof
输出为空。
问题:博文中是否有遗漏的步骤,或者我可能做错了什么或者没有做什么,导致.prof
文件为空?
更新
只是为了澄清,在使用cpu标志启动二进制文件之后,我多次访问我的应用程序的路由,以便它有机会收集数据。在停止程序后,我执行cat filename.prof
,但是它是空的。
一旦我运行以下命令:
go tool pprof havlak1 havlak1.prof
显然我不能再点击我的应用程序了,因为二进制文件没有在运行。(我假设将二进制文件传递给go tool pprof havlak1
除了再次运行/保持运行程序之外还有其他原因)
更新
我是否需要包含代码来手动关闭它写入的文件?我能够使用一个包装程序github.com/davecheney/profile
来对我的应用程序进行性能分析,该程序有一行代码来关闭已打开的文件。
英文:
This blog post provides instructions about how to profile a golang program using the runtime/pprof
package.
In addition to the above mentioned package import, it says (STEP 1) to add this code to the main func
var cpuprofile = flag.String("cpuprofile", "", "write cpu profile to file")
func main() {
flag.Parse()
if *cpuprofile != "" {
f, err := os.Create(*cpuprofile)
if err != nil {
log.Fatal(err)
}
pprof.StartCPUProfile(f)
defer pprof.StopCPUProfile()
}
Then (STEP2) to run the binary (in this case named ./havlak1) passing the name of a file (with extension .prof) to the cpuprofile flag
./havlak1 -cpuprofile=havlak1.prof
Then, after the program stops, (STEP 3) to pass the binary and the .prof
file to the go tool pprof
program
$ go tool pprof havlak1 havlak1.prof
Welcome to pprof! For help, type 'help'.
(pprof)
At this point, the blog author runs the
top10
command to get some output.
I have done each of those steps with my program (but with different binary and .prof file name). However, when I run the top10
command, my program panics with an index out of range error. If I do
cat myfile.prof
to check the contents of the .prof
file, there is no output.
Question: is there a step missing in the blog post or what might I be doing wrong or not doing for the .prof
file to be empty?
Update
Just to clarify, after starting the binary with the cpu flag like this
./havlak1 -cpuprofile=havlak1.prof
I visit the routes of my application a bunch of times to give it an opportunity to collect data. After I stop the program, I do cat filename.prof
and it's empty
Once I run this command
go tool pprof havlak1 havlak1.prof
I can obviously no longer click around my application because the binary isn't running. (I'm assuming the binary is passed to the go tool pprof havlak1
for reasons other than to run the program again/keep it running)
Update
Do I have to include code to manually close the file it writes to? I am able to profile my application using a wrapper program github.com/davecheney/profile
, which has a line that closes the file that's been opened.
答案1
得分: 1
听起来文件没有被写入,而且你似乎在使用延迟语句(defer)来停止分析。如果应用程序在延迟语句运行之前退出,你将无法得到分析结果。
你可以尝试在最后停止分析而不使用延迟语句。
你可以通过编写一个简单的测试并运行go test --cpuprofile=cpu.prof
(所有的Go测试都可以使用该标志自动进行分析),然后通过go tool pprof mypackage.test cpu.prof
来查看结果,以确保问题是你的代码而不是你的机器。
英文:
It sounds like the file isn't being written and it looks like you are using a defer for the profile to stop. If the application exits before that defer can run you won't get the profile written.
You could try to stop the profiling at the end without using a defer statement.
You could make sure the issue is your code and not your machine by writing a simple test and running go test --cpuprofile=cpu.prof
( all go tests can be profiled using that flag automatically) and then viewing the results by go tool pprof mypackage.test cpu.prof
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论