You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
naza/demo/diffpstack/diffpstack.go

142 lines
3.2 KiB
Go

4 years ago
// Copyright 2021, Chef. All rights reserved.
// https://github.com/q191201771/naza
//
// Use of this source code is governed by a MIT-style license
// that can be found in the License file.
//
// Author: Chef (191201771@qq.com)
4 years ago
package main
import (
"fmt"
"io/ioutil"
"strconv"
"strings"
"github.com/q191201771/naza/pkg/nazalog"
)
// 分析c++程序pstack的两次结果的差异
type PstackInfo struct {
tis []ThreadInfo
tim map[string]ThreadInfo
}
type ThreadInfo struct {
Num int
P string
Id int
RawLine string
RawStackLines string
}
func NewPstackInfo(filename string) PstackInfo {
var tis []ThreadInfo
contents, err := ioutil.ReadFile(filename)
nazalog.Assert(nil, err)
content := string(contents)
lines := strings.Split(content, "\n")
//nazalog.Debugf("len(lines)=%d", len(lines))
var ti *ThreadInfo
for _, line := range lines {
if strings.HasPrefix(line, "Thread") {
if ti != nil {
tis = append(tis, *ti)
}
ti = &ThreadInfo{}
//nazalog.Debugf("%s", line)
ti.RawLine = line
ti.Num, ti.P, ti.Id, err = parseThreadLine(line)
nazalog.Assert(nil, err)
continue
}
ti.RawStackLines += line + "\n"
}
if ti != nil {
tis = append(tis, *ti)
}
nazalog.Debugf("len(tis)=%d", len(tis))
tim := make(map[string]ThreadInfo)
for _, ti := range tis {
tim[ti.Uk()] = ti
}
return PstackInfo{
tis: tis,
tim: tim,
}
}
func (pi *PstackInfo) Find(uk string) (ThreadInfo, bool) {
ti, exist := pi.tim[uk]
return ti, exist
}
func (ti *ThreadInfo) Uk() string {
return fmt.Sprintf("%s_%d", ti.P, ti.Id)
}
func parseThreadLine(line string) (num int, p string, id int, err error) {
p1 := strings.Index(line, "Thread")
p2 := strings.Index(line, "(Thread")
num, err = strconv.Atoi(line[p1+7 : p2-1])
if err != nil {
return
}
p3 := strings.Index(line, "(LWP")
p = line[p2+8 : p3-1]
p4 := strings.Index(line, "))")
id, err = strconv.Atoi(line[p3+5 : p4-1])
return
}
func main() {
_ = nazalog.Init(func(option *nazalog.Option) {
option.LevelFlag = false
option.ShortFileFlag = false
option.TimestampFlag = false
})
pi1 := NewPstackInfo("old.txt")
pi2 := NewPstackInfo("new.txt")
for _, ti2 := range pi2.tis {
var pre, suf string
suf = "\033[0m"
ti1, exist := pi1.Find(ti2.Uk())
if exist {
if ti2.RawStackLines == ti1.RawStackLines {
// 1, 2都有但是堆栈没变 没色
pre = ""
suf = ""
nazalog.Debugf("%s-------------------------------------------------------------------------%s", pre, suf)
nazalog.Debugf("%s%s%s", pre, ti2.RawLine, suf)
nazalog.Debugf("%s%s%s", pre, ti2.RawStackLines, suf)
} else {
// 1, 2都有但是堆栈变化 红色
// 注意,断站有变化也可能是函数参数变化了
pre = "\033[22;31m"
nazalog.Debugf("%s-------------------------------------------------------------------------%s", pre, suf)
nazalog.Debugf("%s%s%s", pre, ti2.RawLine, suf)
nazalog.Debugf("%s%s%s", pre, ti2.RawStackLines, suf)
}
} else {
// 只在2有 绿色
pre = "\033[22;36m"
nazalog.Debugf("%s-------------------------------------------------------------------------%s", pre, suf)
nazalog.Debugf("%s%s%s", pre, ti2.RawLine, suf)
nazalog.Debugf("%s%s%s", pre, ti2.RawStackLines, suf)
}
}
}