解决windows系统下go-torch报错: Failed: could not parse raw pprof output: strconv.ParseInt: XXXXXX

1. 错误信息

安装go-torch后,执行指令报“Failed: could not parse raw pprof output: strconv.ParseInt: parsing "os.(File).Write": invalid syntax”或者其他类似的 could not parse raw pprof output错误
在这里插入图片描述

2. 错误原因

先直接说原因哈,着急的同学看到这就可以了:

go sdk 安装到C:\Program Files,文件夹名有空格导致!!!
go sdk 安装到C:\Program Files,文件夹名有空格导致!!!
go sdk 安装到C:\Program Files,文件夹名有空格导致!!!

3. 错误分析

  1. 下载go-torch源码

  2. 根据错误提示“Failed: could not parse raw pprof output”找到在源码的位置(main.go文件)
    在这里插入图片描述

  3. 由此处可以看出是pprof.ParseRaw函数返回的错误

  4. 点到这个方法里面,在可能出问题的地方加上断点,一点一点调试(具体过程略)。最终分析到在pprof/parse文件的processLine方法中出现问题(如下图)
    在这里插入图片描述

  5. 继续深入分析该方法,在pprof/parse文件的180行发现问题,继续深入发现问题根因
    在这里插入图片描述
    在这里插入图片描述

  6. 上面已经猜测了问题出现的原因,那么如何验证呢?

  7. go-torch的原理其实是执行pprof的指令,解析抽样采集文件的信息,大家在执行go-torch指令时都可以看到这一行(如下图),我们可以手动执行“go tool pprof -raw -seconds 30 [source]”命令,或者修改go-torch代码,把pprof解析后的值打印出来(pprof/pprof文件)
    在这里插入图片描述在这里插入图片描述

  8. 根据打印出的值来看(有点多,仅贴部分),搜索关键词“os.(File).Write”发现在这里有出现,结合第5步出现的addLocation方法逻辑分析,因为这行数据中的地址信息多了“空格”,导致在按空格分割后,切片长度为4,导出走错了逻辑,到此为止问题已分析完毕
    在这里插入图片描述

4. 错误修复

那么既然已经发现问题,那如何修复问题呢

第一种: go sdk换个文件夹装,前提是改文件全路径不允许出现空格

第二种:修改go-torch源代码,重新编包

// pprof/pprof文件修改
func runPProf(args ...string) ([]byte, error) {
	allArgs := []string{"tool", "pprof", "-raw"}
	allArgs = append(allArgs, args...)

	var buf bytes.Buffer
	torchlog.Printf("Run pprof command: go %v", strings.Join(allArgs, " "))
	cmd := exec.Command("go", allArgs...)
	cmd.Stderr = &buf
	out, err := cmd.Output()
	if err != nil {
		return nil, fmt.Errorf("pprof error: %v\nSTDERR:\n%s", err, buf.Bytes())
	}

	// @HACK because 'go tool pprof' doesn't exit on errors with nonzero status codes.
	// Ironically, this means that Go's own os/exec package does not detect its errors.
	// See issue here https://github.com/golang/go/issues/11510
	if len(out) == 0 {
		return nil, fmt.Errorf("pprof error:\n%s", buf.Bytes())
	}
	fmt.Println(string(out))
	// 解决c盘文件夹出现空格问题,将空格替换掉
	tmp := bytes2string(out)
	tmp = strings.ReplaceAll(tmp, "Program Files", "ProgramFiles")
	out = string2bytes(tmp)
	return out, nil
}
// 字符串和切片零拷贝
func string2bytes(s string) []byte {
	stringHeader := (*reflect.StringHeader)(unsafe.Pointer(&s))
	bh := reflect.SliceHeader{
		Data: stringHeader.Data,
		Len:  stringHeader.Len,
		Cap:  stringHeader.Len,
	}
	return *(*[]byte)(unsafe.Pointer(&bh))
}
func bytes2string(b []byte) string {
	sliceHeader := (*reflect.SliceHeader)(unsafe.Pointer(&b))
	sh := reflect.StringHeader{
		Data: sliceHeader.Data,
		Len:  sliceHeader.Len,
	}
	return *(*string)(unsafe.Pointer(&sh))
}

5. 生成火焰图报错问题

错误信息:could not generate flame graph: fork/exec flamegraph.pl: %1 is not a valid Win32 application 出现该问题就是还没装flamegraph插件

flamegraph安装:

git clone https://github.com/brendangregg/FlameGraph.git
将当前路径添加到windows系统环境变量下

perl sdk安装:

推荐网盘下载:https://pan.baidu.com/s/107UTzX-9_vgFPTW93Ec3AA
安装教程随便搜都有,这里就不介绍了
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值