Skip to content

Commit d401b9d

Browse files
committed
pkg/manager: add Rank column with tooltips to the main page
1 parent 030f691 commit d401b9d

File tree

6 files changed

+122
-12
lines changed

6 files changed

+122
-12
lines changed

pkg/html/pages/style.css

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,12 @@ table td, table th {
177177
text-align: right;
178178
}
179179

180+
.list_table .rank {
181+
width: 55pt;
182+
font-family: monospace;
183+
text-align: right;
184+
}
185+
180186
.list_table .discussions {
181187
font-family: monospace;
182188
text-align: left;
@@ -493,3 +499,19 @@ aside {
493499

494500
/* Change the background color of the dropdown button when the dropdown content is shown */
495501
.dropdown:hover .dropbtn {background-color: #ddd;}
502+
503+
.rank .tooltiptext {
504+
visibility: hidden;
505+
background-color: black;
506+
color: #fff;
507+
text-align: left;
508+
border-radius: 6px;
509+
padding: 5px 0;
510+
511+
/* Position the tooltip */
512+
position: absolute;
513+
z-index: 1;
514+
}
515+
.rank:hover .tooltiptext {
516+
visibility: visible;
517+
}

pkg/manager/crash.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,13 +216,15 @@ type CrashInfo struct {
216216
type BugInfo struct {
217217
ID string
218218
Title string
219+
TailTitles []*report.TitleFreqRank
219220
FirstTime time.Time
220221
LastTime time.Time
221222
HasRepro bool
222223
HasCRepro bool
223224
StraceFile string // relative to the workdir
224225
ReproAttempts int
225226
Crashes []*CrashInfo
227+
Rank int
226228
}
227229

228230
func (cs *CrashStore) BugInfo(id string, full bool) (*BugInfo, error) {
@@ -238,6 +240,16 @@ func (cs *CrashStore) BugInfo(id string, full bool) (*BugInfo, error) {
238240
return nil, err
239241
}
240242
ret.Title = strings.TrimSpace(string(desc))
243+
244+
// Bug rank may go up over time if we observe higher ranked bugs as a consequence of the first failure.
245+
ret.Rank = report.TitlesToImpact(ret.Title)
246+
if titleStat, err := report.ReadStatFile(filepath.Join(dir, "title-stat")); err == nil {
247+
ret.TailTitles = report.ExplainTitleStat(titleStat)
248+
for _, ti := range ret.TailTitles {
249+
ret.Rank = max(ret.Rank, ti.Rank)
250+
}
251+
}
252+
241253
ret.FirstTime = osutil.CreationTime(stat)
242254
ret.LastTime = stat.ModTime()
243255
files, err := osutil.ListDir(dir)

pkg/manager/html/main.html

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
<thead>
2727
<tr>
2828
<th><a onclick="return sortTable(this, 'Description', textSort)" href="#">Description</a></th>
29+
<th><a onclick="return sortTable(this, 'Rank', numSort)" href="#">Rank</a></th>
2930
<th><a onclick="return sortTable(this, 'Count', numSort)" href="#">Count</a></th>
3031
<th><a onclick="return sortTable(this, 'First Time', textSort, true)" href="#">First Time</a></th>
3132
<th><a onclick="return sortTable(this, 'Last Time', textSort, true)" href="#">Last Time</a></th>
@@ -37,6 +38,14 @@
3738
{{range $c := $.Crashes}}
3839
<tr>
3940
<td class="title"><a href="/crash?id={{$c.ID}}">{{$c.Title}}</a></td>
41+
<td class="rank {{if not $c.Active}}inactive{{end}}">
42+
{{if $c.RankTooltip}}
43+
<b>{{$c.Rank}}</b>
44+
<pre class="tooltiptext">{{$c.RankTooltip}}</pre>
45+
{{else}}
46+
{{$c.Rank}}
47+
{{end}}
48+
</td>
4049
<td class="stat {{if not $c.Active}}inactive{{end}}">{{len $c.Crashes}}</td>
4150
<td class="time {{if not $c.New}}inactive{{end}}">{{formatTime $c.FirstTime}}</td>
4251
<td class="time {{if not $c.Active}}inactive{{end}}">{{formatTime $c.LastTime}}</td>

pkg/manager/http.go

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import (
2929
"github.com/google/syzkaller/pkg/html/pages"
3030
"github.com/google/syzkaller/pkg/log"
3131
"github.com/google/syzkaller/pkg/mgrconfig"
32+
"github.com/google/syzkaller/pkg/report"
3233
"github.com/google/syzkaller/pkg/stat"
3334
"github.com/google/syzkaller/pkg/vcs"
3435
"github.com/google/syzkaller/pkg/vminfo"
@@ -355,12 +356,33 @@ func makeUICrashType(info *BugInfo, startTime time.Time, repros map[string]bool)
355356
triaged := reproStatus(info.HasRepro, info.HasCRepro, repros[info.Title],
356357
info.ReproAttempts >= MaxReproAttempts)
357358
return UICrashType{
358-
BugInfo: *info,
359-
New: info.FirstTime.After(startTime),
360-
Active: info.LastTime.After(startTime),
361-
Triaged: triaged,
362-
Crashes: crashes,
359+
BugInfo: *info,
360+
RankTooltip: higherRankTooltip(info.Title, info.TailTitles),
361+
New: info.FirstTime.After(startTime),
362+
Active: info.LastTime.After(startTime),
363+
Triaged: triaged,
364+
Crashes: crashes,
365+
}
366+
}
367+
368+
// higherRankTooltip generates the prioritized list of the titles with higher Rank
369+
// than the firstTitle has.
370+
func higherRankTooltip(firstTitle string, titlesInfo []*report.TitleFreqRank) string {
371+
baseRank := report.TitlesToImpact(firstTitle)
372+
res := ""
373+
for _, ti := range titlesInfo {
374+
if ti.Rank <= baseRank {
375+
continue
376+
}
377+
res += fmt.Sprintf("[rank %2v, freq %5.1f%%] %s\n",
378+
ti.Rank,
379+
100*float32(ti.Count)/float32(ti.Total),
380+
ti.Title)
381+
}
382+
if res != "" {
383+
return fmt.Sprintf("[rank %2v, originally] %s\n%s", baseRank, firstTitle, res)
363384
}
385+
return res
364386
}
365387

366388
var crashIDRe = regexp.MustCompile(`^\w+$`)
@@ -1024,10 +1046,11 @@ type UICrashPage struct {
10241046

10251047
type UICrashType struct {
10261048
BugInfo
1027-
New bool // was first found in the current run
1028-
Active bool // was found in the current run
1029-
Triaged string
1030-
Crashes []UICrash
1049+
RankTooltip string
1050+
New bool // was first found in the current run
1051+
Active bool // was found in the current run
1052+
Triaged string
1053+
Crashes []UICrash
10311054
}
10321055

10331056
type UICrash struct {

pkg/report/impact_score.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
package report
55

66
import (
7+
"sort"
8+
79
"github.com/google/syzkaller/pkg/report/crash"
810
)
911

@@ -62,3 +64,45 @@ func TitlesToImpact(title string, otherTitles ...string) int {
6264
}
6365
return maxImpact
6466
}
67+
68+
type TitleFreqRank struct {
69+
Title string
70+
Count int
71+
Total int
72+
Rank int
73+
}
74+
75+
func ExplainTitleStat(ts *titleStat) []*TitleFreqRank {
76+
titleCount := map[string]int{}
77+
var totalCount int
78+
ts.visit(func(count int, titles ...string) {
79+
uniq := map[string]bool{}
80+
for _, title := range titles {
81+
uniq[title] = true
82+
}
83+
for title := range uniq {
84+
titleCount[title] += count
85+
}
86+
totalCount += count
87+
})
88+
var res []*TitleFreqRank
89+
for title, count := range titleCount {
90+
res = append(res, &TitleFreqRank{
91+
Title: title,
92+
Count: count,
93+
Total: totalCount,
94+
Rank: TitlesToImpact(title),
95+
})
96+
}
97+
sort.Slice(res, func(l, r int) bool {
98+
if res[l].Rank != res[r].Rank {
99+
return res[l].Rank > res[r].Rank
100+
}
101+
lTitle, rTitle := res[l].Title, res[r].Title
102+
if titleCount[lTitle] != titleCount[rTitle] {
103+
return titleCount[lTitle] > titleCount[rTitle]
104+
}
105+
return lTitle < rTitle
106+
})
107+
return res
108+
}

pkg/report/title_stat.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@ func AddTitleStat(file string, reps []*Report) error {
1616
for _, rep := range reps {
1717
titles = append(titles, rep.Title)
1818
}
19-
stat, err := readStatFile(file)
19+
stat, err := ReadStatFile(file)
2020
if err != nil {
21-
return fmt.Errorf("readStatFile: %w", err)
21+
return fmt.Errorf("report.ReadStatFile: %w", err)
2222
}
2323
stat.add(titles)
2424
if err := writeStatFile(file, stat); err != nil {
@@ -27,7 +27,7 @@ func AddTitleStat(file string, reps []*Report) error {
2727
return nil
2828
}
2929

30-
func readStatFile(file string) (*titleStat, error) {
30+
func ReadStatFile(file string) (*titleStat, error) {
3131
stat := &titleStat{}
3232
if _, err := os.Stat(file); errors.Is(err, os.ErrNotExist) {
3333
return stat, nil

0 commit comments

Comments
 (0)