in agent/checkospanic/checkospanic_linux.go [103:163]
func ParseVmcore(logger logrus.FieldLogger, vmcoreDmesgPath string) (rip, callTrace, panicInfo, rawContent string, err error) {
var (
callTraceLines []string
rawContentBeforPanicInfo []string
rawContentAfterPanicInfo []string
)
var vmcoreFile *os.File
vmcoreFile, err = os.Open(vmcoreDmesgPath)
if err != nil {
logger.Error("open vmcore dmesg file failed: ", err)
return
}
defer vmcoreFile.Close()
scanner := bufio.NewScanner(vmcoreFile)
scanner.Split(bufio.ScanLines)
panicInfo, rawContentBeforPanicInfo = parsePanicInfo(scanner, maxLinesBeforePanicInfo)
if panicInfo == "" {
err = fmt.Errorf("panic info not found")
return
}
// found panicInfo, go on to find rip and call trace
var inCallTrace bool
var done int = 2 // two items need find: callTrace and rip
for done != 0 && scanner.Scan() {
line := scanner.Text()
if len(rawContentAfterPanicInfo) < maxLinesAfterPanicInfo {
rawContentAfterPanicInfo = append(rawContentAfterPanicInfo, line)
}
if strings.Contains(strings.ToLower(line), "call trace:") {
if inCallTrace {
break
}
inCallTrace = true
continue
}
if inCallTrace {
if reLinuxCallTraceMatch.MatchString(line) {
callTraceLines = append(callTraceLines, line)
} else {
done--
}
}
if rip != "" && reRIPMatch.MatchString(line) {
rip = reRIPMatch.FindStringSubmatch(line)[1]
done--
}
}
for len(rawContentAfterPanicInfo) < maxLinesAfterPanicInfo && scanner.Scan() {
rawContentAfterPanicInfo = append(rawContentAfterPanicInfo, scanner.Text())
}
callTrace = strings.Join(callTraceLines, "\n")
rawContent = strings.Join(rawContentBeforPanicInfo, "\n")
if len(rawContentAfterPanicInfo) > 0 {
rawContent = rawContent + "\n" + strings.Join(rawContentAfterPanicInfo, "\n")
}
return
}