58 lines
1.1 KiB
Go
58 lines
1.1 KiB
Go
package fingerprint
|
|
|
|
import (
|
|
"regexp"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
// Generic fallback patterns for common crash formats.
|
|
var (
|
|
// "at function_name (file.c:42)" or "in function_name at file.c:42"
|
|
genericAtRe = regexp.MustCompile(
|
|
`(?:at|in)\s+(\S+)\s+(?:\()?([^:)\s]+):(\d+)`,
|
|
)
|
|
// "function_name+0x1234" (Linux kernel style, perf, etc.)
|
|
genericOffsetRe = regexp.MustCompile(
|
|
`^\s*(?:#\d+\s+)?(\S+)\+(0x[0-9a-fA-F]+)`,
|
|
)
|
|
)
|
|
|
|
// ParseGeneric is a fallback parser that tries heuristic patterns.
|
|
func ParseGeneric(raw string) []Frame {
|
|
var frames []Frame
|
|
|
|
for _, line := range strings.Split(raw, "\n") {
|
|
line = strings.TrimSpace(line)
|
|
if line == "" {
|
|
continue
|
|
}
|
|
|
|
if m := genericAtRe.FindStringSubmatch(line); m != nil {
|
|
lineNo, _ := strconv.Atoi(m[3])
|
|
frames = append(frames, Frame{
|
|
Function: m[1],
|
|
File: m[2],
|
|
Line: lineNo,
|
|
Index: len(frames),
|
|
})
|
|
continue
|
|
}
|
|
|
|
if m := genericOffsetRe.FindStringSubmatch(line); m != nil {
|
|
frames = append(frames, Frame{
|
|
Function: m[1],
|
|
Address: m[2],
|
|
Index: len(frames),
|
|
})
|
|
continue
|
|
}
|
|
}
|
|
|
|
if len(frames) < 2 {
|
|
return nil
|
|
}
|
|
|
|
return frames
|
|
}
|