package fingerprint import ( "regexp" "strconv" "strings" ) // GDB backtrace frame patterns: // #0 function_name (args) at /path/to/file.c:42 // #0 0x00007fff in function_name () from /lib/libfoo.so // #0 0x00007fff in ?? () var gdbFrameRe = regexp.MustCompile( `^\s*#(\d+)\s+(?:(0x[0-9a-fA-F]+)\s+in\s+)?(\S+)\s*\(([^)]*)\)\s*(?:at\s+(\S+?)(?::(\d+))?)?(?:\s+from\s+(\S+))?`, ) // ParseGDB parses GDB/LLDB backtrace format. func ParseGDB(raw string) []Frame { if !strings.Contains(raw, "#0") { return nil } var frames []Frame for _, line := range strings.Split(raw, "\n") { m := gdbFrameRe.FindStringSubmatch(line) if m == nil { continue } idx, _ := strconv.Atoi(m[1]) addr := m[2] fn := m[3] // args := m[4] // ignored file := m[5] lineNo, _ := strconv.Atoi(m[6]) module := m[7] // Skip unknown frames. if fn == "??" { continue } frames = append(frames, Frame{ Index: idx, Address: addr, Function: fn, File: file, Line: lineNo, Module: module, }) } if len(frames) < 2 { return nil // Probably not a real GDB backtrace } return frames }