`go tool pprof` reports error `unrecognized profile format`

huangapple go评论113阅读模式
英文:

`go tool pprof` reports error `unrecognized profile format`

问题

我正在尝试使用这个示例生成goroutine的PNG文件,但是报错显示parsing profile: unrecognized profile format. failed to fetch any source profiles

package main

import (
	"fmt"
	"log"
	"os"
	"os/exec"
	"runtime/pprof"
	"time"
)

func main() {
	// 启动示例的goroutine
	go func() {
		for {
			time.Sleep(time.Second)
		}
	}()

	// 获取可执行二进制文件路径
	exePath, err := os.Executable()
	if err != nil {
		log.Println(err.Error())
		return
	}
	log.Println("exePath", exePath)

	// 生成goroutine profile
	profilePath := exePath + ".profile"
	f, err := os.Create(profilePath)
	if err != nil {
		log.Println(err.Error())
		return
	}
	defer f.Close()
	if err := pprof.Lookup("goroutine").WriteTo(f, 2); err != nil {
		log.Println(err.Error())
		return
	}

	// 生成PNG
	pngPath := exePath + ".png"
	result, err := exec.Command("go", "tool", "pprof", "-png", "-output", pngPath, exePath, profilePath).CombinedOutput()
	if err != nil {
		log.Println("make error:", err.Error())
	}
	log.Println("make result:", string(result))
}
英文:

I am trying to generate PNG of goroutine profile with this demo, but it reports error parsing profile: unrecognized profile format. failed to fetch any source profiles

package main

import (
	"fmt"
	"log"
	"os"
	"os/exec"
	"runtime/pprof"
	"time"
)

func main()  {
	// start demo go routine
	go func() {
		for {
			time.Sleep(time.Second)
		}
	}()

	// get executable binary path
	exePath, err := os.Executable()
	if err != nil {
		log.Println(err.Error())
		return
	}
	log.Println("exePath", exePath)

	// generate goroutine profile
	profilePath := exePath + ".profile"
	f, err := os.Create(profilePath)
	if err != nil {
		log.Println(err.Error())
		return
	}
	defer f.Close()
	if err := pprof.Lookup("goroutine").WriteTo(f, 2); err != nil {
		log.Println(err.Error())
		return
	}

	// generate PNG
	pngPath := exePath + ".png"
	result, err := exec.Command("go", "tool", "pprof", "-png", "-output", pngPath, exePath, profilePath).CombinedOutput()
	if err != nil {
		log.Println("make error:", err.Error())
	}
	log.Println("make result:", string(result))
}

答案1

得分: 2

您正在pprof.Lookup("goroutine").WriteTo(f, 2)中使用调试值2。这将生成一个输出,pprof工具无法解析,它是为了直接人类可读而设计的。

根据pprof.(*Profile).WriteTo文档:

调试参数启用了额外的输出。传递debug=0会写入gzip压缩的协议缓冲区,详见https://github.com/google/pprof/tree/master/proto#overview。传递debug=1会写入带有注释的传统文本格式,将地址转换为函数名和行号,以便程序员可以在没有工具的情况下阅读配置文件。

预定义的配置文件可能会为其他调试值分配含义;例如,在打印“goroutine”配置文件时,debug=2表示以与Go程序由于未恢复的恐慌而死亡时使用的形式打印goroutine堆栈。

将此行更改为pprof.Lookup("goroutine").WriteTo(f, 0)可以解决问题。


此外,与问题无关,但您可能希望在使用pprof命令之前关闭文件f.Close()WriteTo应该将文件刷新到磁盘,但这样做不会有害。

if err := pprof.Lookup("goroutine").WriteTo(f, 2); err != nil {
    log.Println(err.Error())
    return
}

if err := f.Close(); err != nil {
    log.Println(err.Error())
    return
}

// 生成PNG
...
英文:

You are using a debug value of 2 in pprof.Lookup("goroutine").WriteTo(f, 2). This will produce an output which the pprof tool can't parse, it is meant as directly human readable.

From the pprof.(*Profile).WriteTo docs:

>The debug parameter enables additional output. Passing debug=0 writes the gzip-compressed protocol buffer described in https://github.com/google/pprof/tree/master/proto#overview. Passing debug=1 writes the legacy text format with comments translating addresses to function names and line numbers, so that a programmer can read the profile without tools.
>
>The predefined profiles may assign meaning to other debug values; for example, when printing the "goroutine" profile, debug=2 means to print the goroutine stacks in the same form that a Go program uses when dying due to an unrecovered panic.

Changing this line to pprof.Lookup("goroutine").WriteTo(f, 0) resolves the issue.


Also, not relevant to the issue, but you might want to consider closing the file f.Close() before using it in the pprof command. WriteTo should flush the file to disk, but it can't hurt.

if err := pprof.Lookup("goroutine").WriteTo(f, 2); err != nil {
    log.Println(err.Error())
    return
}

if err := f.Close(); err != nil {
    log.Println(err.Error())
    return
}

// generate PNG
...

huangapple
  • 本文由 发表于 2021年12月11日 21:11:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/70315426.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定