func ParseVmcore()

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
}