Index: fuzzer/go/frontend/data/stacktrace.go |
diff --git a/fuzzer/go/frontend/data/stacktrace.go b/fuzzer/go/frontend/data/stacktrace.go |
index 5c9e657fccb1f1c2bfc94f1a7f7e82887e6cde47..b13e731a739aadfff3c228a4a034a3c933dc1ce7 100644 |
--- a/fuzzer/go/frontend/data/stacktrace.go |
+++ b/fuzzer/go/frontend/data/stacktrace.go |
@@ -25,10 +25,11 @@ type StackTraceFrame struct { |
// The `?:` at the beginning of the groups prevent them from being captured |
// \1 is the "package", \2 is the file name, \3 is the line number, \4 is the function symbol string |
-var stackTraceLine = regexp.MustCompile(`(?:\.\./)+(?P<package>(?:\w+/)+)(?P<file>.+):(?P<line>\d+).*\(_(?P<symbol>.*)\)`) |
+var segvStackTraceLine = regexp.MustCompile(`(?:\.\./)+(?P<package>(?:\w+/)+)(?P<file>.+):(?P<line>\d+).*\(_(?P<symbol>.*)\)`) |
-// Given the files of a dump file (created through get_stack_trace [which uses catchsegv]), return the stack trace |
-func ParseStackTrace(contents string) StackTrace { |
+// parseCatchsegvStackTrace takes the contents of a dump file of a catchsegv run, and returns the |
+// parsed stacktrace |
+func parseCatchsegvStackTrace(contents string) StackTrace { |
r := bytes.NewBufferString(contents) |
scan := bufio.NewScanner(r) |
@@ -48,10 +49,10 @@ func ParseStackTrace(contents string) StackTrace { |
continue |
} |
- if match := stackTraceLine.FindStringSubmatch(line); match != nil { |
+ if match := segvStackTraceLine.FindStringSubmatch(line); match != nil { |
// match[0] is the entire matched portion, [1] is the "package", [2] is the file name, |
// [3] is the line number and [4] is the encoded function symbol string. |
- newFrame := FullStackFrame(match[1], match[2], decodeFunctionName(match[4]), safeParseInt(match[3])) |
+ newFrame := FullStackFrame(match[1], match[2], catchsegvFunctionName(match[4]), safeParseInt(match[3])) |
frames = append(frames, newFrame) |
} |
} |
@@ -76,7 +77,7 @@ var nonstaticStart = regexp.MustCompile(`^Z(\d+)`) |
var methodStart = regexp.MustCompile(`^(ZNK?)(\d+)`) |
var methodName = regexp.MustCompile(`^(\d+)`) |
-// decodeFunctionName parses the symbol string from a stacktrace to |
+// catchsegvFunctionName parses the symbol string from a stacktrace to |
// get the name of the related function. |
//TODO(kjlubick) parse arguments if that helps the readability of the stacktraces |
// Here are some examples of symbol strings and what the various chars mean: |
@@ -87,7 +88,7 @@ var methodName = regexp.MustCompile(`^(\d+)`) |
// ZNK2DM6SKPSrc4drawEP8SkCanvas -> ZNK2 -> type is 2 long (method is konstant) "DM" -> |
// 6 -> Sub type is 6 long "SKPSrc" -> 4 -> method is 4 long "draw" |
// (since there is no number directly after the 3rd step, we have found the param boundary). |
-func decodeFunctionName(s string) string { |
+func catchsegvFunctionName(s string) string { |
if match := methodStart.FindStringSubmatch(s); match != nil { |
length := safeParseInt(match[2]) |
// ZNK? is 2-3 chars, so slice (num letters + num digits + number of spaces) chars off |
@@ -124,6 +125,45 @@ func decodeFunctionName(s string) string { |
return common.UNKNOWN_FUNCTION |
} |
+// The `?:` at the beginning of the groups prevent them from being captured |
+// \1 is the (hopefully symbolized) function name, \2 is the "package", \3 is the file name, |
+// \4 is the line number |
+var asanStackTraceLine = regexp.MustCompile(`in (?P<function>[a-zA-Z0-9_:]+).*(?:\.\./)+(?P<package>(?:\w+/)+)(?P<file>.+?):(?P<line>\d+)`) |
+ |
+// parseCatchsegvStackTrace takes the output of an AddressSanitizer crash, and returns the parsed |
+// StackTrace, if it is able to find one. If the result is not symbolized, this will return |
+// an empty StackTrace. |
+func parseASANStackTrace(contents string) StackTrace { |
+ r := bytes.NewBufferString(contents) |
+ scan := bufio.NewScanner(r) |
+ |
+ hasBegun := false |
+ |
+ frames := make([]StackTraceFrame, 0, 5) |
+ |
+ for scan.Scan() { |
+ line := scan.Text() |
+ if strings.Contains(line, "ERROR: AddressSanitizer:") { |
+ hasBegun = true |
+ continue |
+ } |
+ if hasBegun && line == "" { |
+ break |
+ } |
+ if !hasBegun { |
+ continue |
+ } |
+ |
+ if match := asanStackTraceLine.FindStringSubmatch(line); match != nil { |
+ // match[0] is the entire matched portion, [1] is the function name [2] is the |
+ // "package", [3] is the file name, [4] is the line number |
+ newFrame := FullStackFrame(match[2], match[3], match[1], safeParseInt(match[4])) |
+ frames = append(frames, newFrame) |
+ } |
+ } |
+ return StackTrace{Frames: frames} |
+} |
+ |
// FullStackFrame creates a StackTraceFrame with all components |
func FullStackFrame(packageName, fileName, functionName string, lineNumber int) StackTraceFrame { |
return StackTraceFrame{ |