cairn/internal/fingerprint/parser_gdb.go

59 lines
1.1 KiB
Go

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
}