Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(331)

Unified Diff: fuzzer/go/frontend/data/result.go

Issue 1691893002: Fuzzer now deduplicates on the analysis side instead of the download side (Closed) Base URL: https://skia.googlesource.com/buildbot@metrics
Patch Set: Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « fuzzer/go/frontend/data/report_test.go ('k') | fuzzer/go/frontend/data/stacktrace.go » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: fuzzer/go/frontend/data/result.go
diff --git a/fuzzer/go/frontend/data/result.go b/fuzzer/go/frontend/data/result.go
deleted file mode 100644
index 7dfb7cb5a67996eea5ea8c785a7ec1175b71e559..0000000000000000000000000000000000000000
--- a/fuzzer/go/frontend/data/result.go
+++ /dev/null
@@ -1,252 +0,0 @@
-package data
-
-import (
- "fmt"
- "regexp"
- "sort"
- "strings"
-
- "go.skia.org/infra/fuzzer/go/common"
-)
-
-// Represents the metadata about a crash, hopefully easing debugging.
-type FuzzResult struct {
- Debug BuildData
- Release BuildData
-}
-
-// BuildData represents the results of parsing a given skia build's output.
-type BuildData struct {
- OutputFiles
- StackTrace StackTrace
- Flags FuzzFlag
-}
-
-// OutputFiles are the files output by the analysis
-type OutputFiles struct {
- Asan string
- Dump string
- StdErr string
-}
-
-// GCSPackage is a struct containing all the pieces of a fuzz that exist in Google Storage.
-type GCSPackage struct {
- Name string
- FuzzCategory string
- Debug OutputFiles
- Release OutputFiles
-}
-
-// A bit mask representing what happened when a fuzz ran against Skia.
-type FuzzFlag int
-
-const (
- TerminatedGracefully FuzzFlag = 1 << iota
- ClangCrashed
- ASANCrashed
- AssertionViolated
- BadAlloc
- NoStackTrace
- SKAbortHit
- TimedOut
- Other
-
- ASAN_GlobalBufferOverflow
- ASAN_HeapBufferOverflow
- ASAN_StackBufferOverflow
- ASAN_HeapUseAfterFree
-
- SKPICTURE_DuringRendering
-)
-
-var flagNames = []string{
- "FailedGracefully",
- "ClangCrashed",
- "ASANCrashed",
- "AssertionViolated",
- "BadAlloc",
- "NoStackTrace",
- "SKAbortHit",
- "TimedOut",
- "Other",
-
- "ASAN_global-buffer-overflow",
- "ASAN_heap-buffer-overflow",
- "ASAN_stack-buffer-overflow",
- "ASAN_heap-use-after-free",
-
- "SKPICTURE_DuringRendering",
-}
-
-// ToHumanReadableFlags creates a sorted slice of strings that represents the flags. The slice
-// is sorted by unicode points, as per sort.Strings().
-func (f FuzzFlag) ToHumanReadableFlags() []string {
- flags := make([]string, 0)
- i := 0
- for mask := 1; mask < (2 << 16); mask *= 2 {
- if int(f)&mask != 0 {
- flags = append(flags, flagNames[i])
- }
- i++
- }
- // Front end filtering logic will expect the flags to be in alphabetical order.
- sort.Strings(flags)
- return flags
-}
-
-func (f FuzzFlag) String() string {
- return fmt.Sprintf("FuzzFlag: %016b (%d) [%s]", f, f, strings.Join(f.ToHumanReadableFlags(), " | "))
-}
-
-// ParseGCSPackage parses the results of analysis of a fuzz and creates a FuzzResult with it.
-// This includes parsing the stacktraces and computing the flags about the fuzz.
-func ParseGCSPackage(g GCSPackage) FuzzResult {
- result := FuzzResult{}
- result.Debug.Asan = g.Debug.Asan
- result.Debug.Dump = g.Debug.Dump
- result.Debug.StdErr = g.Debug.StdErr
- result.Debug.StackTrace = getStackTrace(g.Debug.Asan, g.Debug.Dump)
- result.Release.Asan = g.Release.Asan
- result.Release.Dump = g.Release.Dump
- result.Release.StdErr = g.Release.StdErr
- result.Release.StackTrace = getStackTrace(g.Release.Asan, g.Release.Dump)
- result.computeFlags(g.FuzzCategory)
-
- return result
-}
-
-// getStackTrace creates a StackTrace output from one of the two dumps given. It first tries to
-// use the AddressSanitizer dump, with the Clang dump as a fallback.
-func getStackTrace(asan, dump string) StackTrace {
- if asanCrashed(asan) {
- return parseASANStackTrace(asan)
- }
- return parseCatchsegvStackTrace(dump)
-}
-
-// computeFlags parses the raw data to set both the Debug and Release flags.
-func (r *FuzzResult) computeFlags(category string) {
- r.Debug.Flags = parseAll(category, &r.Debug)
- r.Release.Flags = parseAll(category, &r.Release)
-}
-
-// parseAll looks at the three input files and parses the results, based on the category. The
-// category allows for specialized flags, like SKPICTURE_DuringRendering.
-func parseAll(category string, data *BuildData) FuzzFlag {
- f := FuzzFlag(0)
- // Check for SKAbort message
- if strings.Contains(data.Asan, "fatal error") {
- f |= ASANCrashed
- f |= SKAbortHit
- if data.StackTrace.IsEmpty() {
- data.StackTrace = extractSkAbortTrace(data.StdErr)
- }
- }
- if strings.Contains(data.StdErr, "fatal error") {
- f |= ClangCrashed
- f |= SKAbortHit
- if data.StackTrace.IsEmpty() {
- data.StackTrace = extractSkAbortTrace(data.StdErr)
- }
- }
- // If no sk abort message and no evidence of crashes, we either terminated gracefully or
- // timed out.
- if f == 0 && !asanCrashed(data.Asan) && !clangDumped(data.Dump) {
- if strings.Contains(data.Asan, "[terminated]") && strings.Contains(data.StdErr, "[terminated]") {
- return TerminatedGracefully
- }
- return TimedOut
- }
-
- // Look for clues from the various dumps.
- f |= parseAsan(category, data.Asan)
- f |= parseCatchsegv(category, data.Dump, data.StdErr)
- if f == 0 {
- // I don't know what this means (yet).
- return Other
- }
- if data.StackTrace.IsEmpty() {
- f |= NoStackTrace
- }
- return f
-}
-
-// parseAsan returns the flags discovered while looking through the AddressSanitizer output. This
-// includes things like ASAN_GlobalBufferOverflow.
-func parseAsan(category, asan string) FuzzFlag {
- f := FuzzFlag(0)
- if !asanCrashed(asan) {
- return f
- }
- f |= ASANCrashed
- if strings.Contains(asan, "failed assertion") {
- f |= AssertionViolated
- }
- if strings.Contains(asan, "global-buffer-overflow") {
- f |= ASAN_GlobalBufferOverflow
- }
- if strings.Contains(asan, "heap-buffer-overflow") {
- f |= ASAN_HeapBufferOverflow
- }
- if strings.Contains(asan, "stack-buffer-overflow") {
- f |= ASAN_StackBufferOverflow
- }
- if strings.Contains(asan, "heap-use-after-free") {
- f |= ASAN_HeapUseAfterFree
- }
- if strings.Contains(asan, "AddressSanitizer failed to allocate") {
- f |= BadAlloc
- }
-
- // Split off the stderr that happened before the crash.
- errs := strings.Split(asan, "=================")
- if len(errs) > 0 {
- err := errs[0]
- if category == "skpicture" && strings.Contains(err, "Rendering") {
- f |= SKPICTURE_DuringRendering
- }
- }
- return f
-}
-
-// asanCrashed returns true if the asan output is consistent with a crash.
-func asanCrashed(asan string) bool {
- return strings.Contains(asan, "ERROR: AddressSanitizer:")
-}
-
-// parseAsan returns the flags discovered while looking through the Clang dump and standard error.
-// This includes things like
-func parseCatchsegv(category, dump, err string) FuzzFlag {
- f := FuzzFlag(0)
- if !clangDumped(dump) && strings.Contains(err, "[terminated]") {
- return f
- }
- f |= ClangCrashed
- if strings.Contains(err, "failed assertion") {
- f |= AssertionViolated
- }
- if category == "skpicture" && strings.Contains(err, "Rendering") {
- f |= SKPICTURE_DuringRendering
- }
- if strings.Contains(err, "std::bad_alloc") {
- f |= BadAlloc
- }
- return f
-}
-
-// clangDumped returns true if the clang output is consistent with a crash, that is, non empty.
-func clangDumped(dump string) bool {
- return len(dump) != 0
-}
-
-var skAbortStackTraceLine = regexp.MustCompile(`(?:\.\./)+(?P<package>(?:\w+/)+)(?P<file>.+):(?P<line>\d+): fatal error`)
-
-// extractSkAbortTrace looks for the fatal error string indicative of the SKAbort termination
-// and tries to pull out the stacktrace frame on which it happened.
-func extractSkAbortTrace(err string) StackTrace {
- st := StackTrace{}
- if match := skAbortStackTraceLine.FindStringSubmatch(err); match != nil {
- st.Frames = append(st.Frames, FullStackFrame(match[1], match[2], common.UNKNOWN_FUNCTION, safeParseInt(match[3])))
- }
- return st
-}
« no previous file with comments | « fuzzer/go/frontend/data/report_test.go ('k') | fuzzer/go/frontend/data/stacktrace.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698