diff options
| author | Taras Madan <tarasmadan@google.com> | 2025-07-01 10:15:11 +0200 |
|---|---|---|
| committer | Taras Madan <tarasmadan@google.com> | 2025-07-02 08:52:54 +0000 |
| commit | d94a0369a298b9dd3a9bc17d664840ea6f64401e (patch) | |
| tree | c3b24a3497e8ec085e88f2a12f6ae70bddbd07c6 /pkg | |
| parent | bc80e4f080d226b12fae367dc46bc54ac3681009 (diff) | |
dashboard/app: use crash types instead, no regexps
Diffstat (limited to 'pkg')
| -rw-r--r-- | pkg/report/crash/types.go | 93 | ||||
| -rw-r--r-- | pkg/report/linux.go | 2 | ||||
| -rw-r--r-- | pkg/report/report.go | 4 | ||||
| -rw-r--r-- | pkg/report/report_test.go | 2 | ||||
| -rw-r--r-- | pkg/report/title_to_type.go | 28 | ||||
| -rw-r--r-- | pkg/vcs/linux_configs.go | 86 |
6 files changed, 162 insertions, 53 deletions
diff --git a/pkg/report/crash/types.go b/pkg/report/crash/types.go index 52fba0fbc..ad550fa08 100644 --- a/pkg/report/crash/types.go +++ b/pkg/report/crash/types.go @@ -6,21 +6,28 @@ package crash type Type string const ( - UnknownType = Type("") - Hang = Type("HANG") - MemoryLeak = Type("LEAK") - DataRace = Type("DATARACE") - UnexpectedReboot = Type("REBOOT") - UBSAN = Type("UBSAN") - Bug = Type("BUG") - Warning = Type("WARNING") - KASAN = Type("KASAN") - KFENCE = Type("KFENCE") - LockdepBug = Type("LOCKDEP") - AtomicSleep = Type("ATOMIC_SLEEP") - KMSAN = Type("KMSAN") - SyzFailure = Type("SYZ_FAILURE") + UnknownType = Type("") + // keep-sorted start + AtomicSleep = Type("ATOMIC_SLEEP") + Bug = Type("BUG") + DoS = Type("DoS") + Hang = Type("HANG") + KASAN = Type("KASAN") + KCSAN = Type("KCSAN") + KCSANDataRace = Type("DATARACE") + KFENCE = Type("KFENCE") + KMSAN = Type("KMSAN") + LockdepBug = Type("LOCKDEP") + MemoryLeak = Type("LEAK") + MemorySafetyBUG = Type("MEMORY_SAFETY_BUG") + MemorySafetyUBSAN = Type("MEMORY_SAFETY_UBSAN") + MemorySafetyWARNING = Type("MEMORY_SAFETY_WARNING") + UBSAN = Type("UBSAN") + Warning = Type("WARNING") + // keep-sorted end LostConnection = Type("LOST_CONNECTION") + SyzFailure = Type("SYZ_FAILURE") + UnexpectedReboot = Type("REBOOT") ) func (t Type) String() string { @@ -29,3 +36,61 @@ func (t Type) String() string { } return string(t) } + +type TypeGroupPred func(Type) bool + +func (t Type) IsKASAN() bool { + return t == KASAN +} + +func (t Type) IsKMSAN() bool { + return t == KMSAN +} + +func (t Type) IsKCSAN() bool { + return t == KCSANDataRace || t == KCSAN +} + +func (t Type) IsUBSAN() bool { + return t == UBSAN || t == MemorySafetyUBSAN +} + +func (t Type) IsBUG() bool { + return t == Bug || t == MemorySafetyBUG +} + +func (t Type) IsWarning() bool { + return t == Warning || t == MemorySafetyWARNING +} + +func (t Type) IsBugOrWarning() bool { + return t.IsBUG() || t.IsWarning() +} + +func (t Type) IsMemSafety() bool { + return t == MemorySafetyBUG || t == MemorySafetyWARNING || t == MemorySafetyUBSAN +} + +func (t Type) IsMemoryLeak() bool { + return t == MemoryLeak +} + +func (t Type) IsLockingBug() bool { + return t.IsLockdep() || t.IsAtomicSleep() +} + +func (t Type) IsDoS() bool { + return t == Bug || t == DoS +} + +func (t Type) IsHang() bool { + return t == Hang +} + +func (t Type) IsLockdep() bool { + return t == LockdepBug +} + +func (t Type) IsAtomicSleep() bool { + return t == AtomicSleep +} diff --git a/pkg/report/linux.go b/pkg/report/linux.go index f714e55cd..ff5d6bf4e 100644 --- a/pkg/report/linux.go +++ b/pkg/report/linux.go @@ -188,7 +188,7 @@ func (ctx *linux) Parse(output []byte) *Report { } rep.reportPrefixLen = len(rep.Report) rep.Report = append(rep.Report, report...) - rep.Type = titleToCrashType(rep.Title) + rep.Type = TitleToCrashType(rep.Title) setExecutorInfo(rep) if !rep.Corrupted { rep.Corrupted, rep.CorruptedReason = isCorrupted(title, report, format) diff --git a/pkg/report/report.go b/pkg/report/report.go index 3381607ea..44d4563e2 100644 --- a/pkg/report/report.go +++ b/pkg/report/report.go @@ -800,7 +800,7 @@ func simpleLineParser(output []byte, oopses []*oops, params *stackParams, ignore rep.Report = output[rep.StartPos:] rep.Corrupted = corrupted != "" rep.CorruptedReason = corrupted - rep.Type = titleToCrashType(rep.Title) + rep.Type = TitleToCrashType(rep.Title) return rep } @@ -933,7 +933,7 @@ var groupGoRuntimeErrors = oops{ }, } -func titleToCrashType(title string) crash.Type { +func TitleToCrashType(title string) crash.Type { for _, t := range titleToType { for _, prefix := range t.includePrefixes { if strings.HasPrefix(title, prefix) { diff --git a/pkg/report/report_test.go b/pkg/report/report_test.go index 739068787..2184cd411 100644 --- a/pkg/report/report_test.go +++ b/pkg/report/report_test.go @@ -208,7 +208,7 @@ func testFromReport(rep *Report) *ParseTest { Corrupted: rep.Corrupted, corruptedReason: rep.CorruptedReason, Suppressed: rep.Suppressed, - Type: titleToCrashType(rep.Title), + Type: TitleToCrashType(rep.Title), Frame: rep.Frame, Report: rep.Report, } diff --git a/pkg/report/title_to_type.go b/pkg/report/title_to_type.go index 44f5ccaf9..61c7b6d9d 100644 --- a/pkg/report/title_to_type.go +++ b/pkg/report/title_to_type.go @@ -12,8 +12,29 @@ var titleToType = []struct { crashType crash.Type }{ { + includePrefixes: []string{ + // keep-sorting start + "BUG: corrupted list", + "BUG: unable to handle kernel paging request", + // keep-sorting end + }, + crashType: crash.MemorySafetyBUG, + }, + { + includePrefixes: []string{ + "WARNING: refcount bug", + }, + crashType: crash.MemorySafetyWARNING, + }, + { + includePrefixes: []string{ + "UBSAN: array-index", + }, + crashType: crash.MemorySafetyUBSAN, + }, + { includePrefixes: []string{"KCSAN: data-race"}, - crashType: crash.DataRace, + crashType: crash.KCSANDataRace, }, { includePrefixes: []string{ @@ -23,6 +44,7 @@ var titleToType = []struct { "BUG: rwlock", "BUG: spinlock", "BUG: still has locks held in", + "BUG: using", // BUG: using ... in preemptible ... "WARNING: bad unlock balance in", "WARNING: held lock freed in", "WARNING: lock held", @@ -53,7 +75,6 @@ var titleToType = []struct { includePrefixes: []string{ // keep-sorted start "BUG: bad usercopy in", - "BUG: corrupted list in", "kernel BUG ", // keep-sorted end }, @@ -90,7 +111,6 @@ var titleToType = []struct { // keep-sorted start "Alignment trap in", "BUG: Object already free", - "BUG: unable to handle kernel", "Internal error in", "PANIC: double fault", "Unhandled fault in", @@ -109,7 +129,7 @@ var titleToType = []struct { "unregister_netdevice: waiting for DEV to become free", // keep-sorted end }, - crashType: crash.UnknownType, + crashType: crash.DoS, }, { includePrefixes: []string{"unexpected kernel reboot"}, diff --git a/pkg/vcs/linux_configs.go b/pkg/vcs/linux_configs.go index 8d972edd3..8b59abbc0 100644 --- a/pkg/vcs/linux_configs.go +++ b/pkg/vcs/linux_configs.go @@ -99,46 +99,70 @@ func setLinuxTagConfigs(cf *kconfig.ConfigFile, tags map[string]bool) { // setLinuxSanitizerConfigs() removes Linux kernel sanitizers that are not necessary // to trigger the specified crash types. func setLinuxSanitizerConfigs(cf *kconfig.ConfigFile, types []crash.Type, dt debugtracer.DebugTracer) { - keep := map[crash.Type]func(){ - crash.Hang: func() { - cf.Unset("RCU_STALL_COMMON") - cf.Unset("LOCKUP_DETECTOR") - cf.Unset("SOFTLOCKUP_DETECTOR") - cf.Unset("HARDLOCKUP_DETECTOR") - cf.Unset("DETECT_HUNG_TASK") - // It looks like it's the only reliable way to completely disable hung errors. - cmdline := cf.Value("CMDLINE") - pos := strings.LastIndexByte(cmdline, '"') - const rcuStallSuppress = "rcupdate.rcu_cpu_stall_suppress=1" - if pos >= 0 && !strings.Contains(cmdline, rcuStallSuppress) { - cf.Set("CMDLINE", cmdline[:pos]+" "+rcuStallSuppress+cmdline[pos:]) - } + keep := map[string]struct { + pred crash.TypeGroupPred + disabler func() + }{ + "hang": { + pred: crash.Type.IsHang, + disabler: func() { + cf.Unset("RCU_STALL_COMMON") + cf.Unset("LOCKUP_DETECTOR") + cf.Unset("SOFTLOCKUP_DETECTOR") + cf.Unset("HARDLOCKUP_DETECTOR") + cf.Unset("DETECT_HUNG_TASK") + // It looks like it's the only reliable way to completely disable hung errors. + cmdline := cf.Value("CMDLINE") + pos := strings.LastIndexByte(cmdline, '"') + const rcuStallSuppress = "rcupdate.rcu_cpu_stall_suppress=1" + if pos >= 0 && !strings.Contains(cmdline, rcuStallSuppress) { + cf.Set("CMDLINE", cmdline[:pos]+" "+rcuStallSuppress+cmdline[pos:]) + } + }, + }, + "memleak": { + pred: crash.Type.IsMemoryLeak, + disabler: func() { cf.Unset("DEBUG_KMEMLEAK") }, + }, + "ubsan": { + pred: crash.Type.IsUBSAN, + disabler: func() { cf.Unset("UBSAN") }, }, - crash.MemoryLeak: func() { cf.Unset("DEBUG_KMEMLEAK") }, - crash.UBSAN: func() { cf.Unset("UBSAN") }, - crash.Bug: func() { cf.Unset("BUG") }, - crash.KASAN: func() { cf.Unset("KASAN") }, - crash.LockdepBug: func() { - cf.Unset("LOCKDEP") - cf.Unset("PROVE_LOCKING") // it selects LOCKDEP + "bug_or_warning": { + pred: crash.Type.IsBugOrWarning, + disabler: func() { cf.Unset("BUG") }, + }, + "kasan": { + pred: crash.Type.IsKASAN, + disabler: func() { cf.Unset("KASAN") }, + }, + "locking": { + pred: crash.Type.IsLockdep, + disabler: func() { + cf.Unset("LOCKDEP") + cf.Unset("PROVE_LOCKING") // it selects LOCKDEP + }, + }, + "atomic_sleep": { + pred: crash.Type.IsAtomicSleep, + disabler: func() { cf.Unset("DEBUG_ATOMIC_SLEEP") }, }, - crash.AtomicSleep: func() { cf.Unset("DEBUG_ATOMIC_SLEEP") }, } - need := map[crash.Type]bool{} + need := map[string]bool{} for _, typ := range types { - if typ == crash.Warning { - // These are disabled together. - typ = crash.Bug + for keepName, funcs := range keep { + if funcs.pred(typ) { + need[keepName] = true + } } - need[typ] = true } var disabled []string - for typ, f := range keep { - if need[typ] { + for categoryName, funcs := range keep { + if need[categoryName] { continue } - f() - disabled = append(disabled, string(typ)) + funcs.disabler() + disabled = append(disabled, categoryName) } if len(disabled) > 0 { dt.Log("disabling configs for %v, they are not needed", disabled) |
