60 lines
1.1 KiB
Go
60 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
|
|
}
|