mirror of
https://github.com/reactos/syzkaller.git
synced 2024-11-26 21:00:30 +00:00
pkg: get and store Maintainers data
Create a struct on pkg/vcs to store data of syzkaller email recipients and update its users. The struct contains default name, email, and a label to divide user into To and Cc when sending the emails.
This commit is contained in:
parent
68aca71e8d
commit
242b0eb219
@ -180,7 +180,8 @@ func runImpl(cfg *Config, repo vcs.Repo, inst instance.Env) (*Result, error) {
|
||||
}
|
||||
com := res.Commits[0]
|
||||
env.log("first %v commit: %v %v", what, com.Hash, com.Title)
|
||||
env.log("cc: %q", com.CC)
|
||||
env.log("recipients (to): %q", com.Recipients.GetEmails(vcs.To))
|
||||
env.log("recipients (cc): %q", com.Recipients.GetEmails(vcs.Cc))
|
||||
if res.Report != nil {
|
||||
env.log("crash: %v\n%s", res.Report.Title, res.Report.Report)
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ import (
|
||||
|
||||
"github.com/google/syzkaller/pkg/osutil"
|
||||
"github.com/google/syzkaller/pkg/report"
|
||||
"github.com/google/syzkaller/pkg/vcs"
|
||||
)
|
||||
|
||||
// Params is input arguments for the Image function.
|
||||
@ -90,10 +91,10 @@ func Clean(targetOS, targetArch, vmType, kernelDir string) error {
|
||||
}
|
||||
|
||||
type KernelError struct {
|
||||
Report []byte
|
||||
Output []byte
|
||||
Maintainers []string
|
||||
guiltyFile string
|
||||
Report []byte
|
||||
Output []byte
|
||||
Recipients vcs.Recipients
|
||||
guiltyFile string
|
||||
}
|
||||
|
||||
func (err *KernelError) Error() string {
|
||||
@ -195,7 +196,7 @@ func extractRootCause(err error, OS, kernelSrc string) error {
|
||||
if err != nil {
|
||||
kernelErr.Output = append(kernelErr.Output, err.Error()...)
|
||||
}
|
||||
kernelErr.Maintainers = maintainers
|
||||
kernelErr.Recipients = maintainers
|
||||
}
|
||||
return kernelErr
|
||||
}
|
||||
|
@ -7,7 +7,6 @@ import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"net/mail"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strconv"
|
||||
@ -16,6 +15,7 @@ import (
|
||||
|
||||
"github.com/google/syzkaller/pkg/osutil"
|
||||
"github.com/google/syzkaller/pkg/symbolizer"
|
||||
"github.com/google/syzkaller/pkg/vcs"
|
||||
)
|
||||
|
||||
type linux struct {
|
||||
@ -351,7 +351,7 @@ func (ctx *linux) Symbolize(rep *Report) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rep.Maintainers = maintainers
|
||||
rep.Recipients = maintainers
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@ -466,14 +466,14 @@ nextFile:
|
||||
return ""
|
||||
}
|
||||
|
||||
func (ctx *linux) getMaintainers(file string) ([]string, error) {
|
||||
func (ctx *linux) getMaintainers(file string) (vcs.Recipients, error) {
|
||||
if ctx.kernelSrc == "" {
|
||||
return nil, nil
|
||||
}
|
||||
return GetLinuxMaintainers(ctx.kernelSrc, file)
|
||||
}
|
||||
|
||||
func GetLinuxMaintainers(kernelSrc, file string) ([]string, error) {
|
||||
func GetLinuxMaintainers(kernelSrc, file string) (vcs.Recipients, error) {
|
||||
mtrs, err := getMaintainersImpl(kernelSrc, file, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -487,9 +487,9 @@ func GetLinuxMaintainers(kernelSrc, file string) ([]string, error) {
|
||||
return mtrs, nil
|
||||
}
|
||||
|
||||
func getMaintainersImpl(kernelSrc, file string, blame bool) ([]string, error) {
|
||||
func getMaintainersImpl(kernelSrc, file string, blame bool) (vcs.Recipients, error) {
|
||||
// See #1441 re --git-min-percent.
|
||||
args := []string{"--no-n", "--no-rolestats", "--git-min-percent=15"}
|
||||
args := []string{"--git-min-percent=15"}
|
||||
if blame {
|
||||
args = append(args, "--git-blame")
|
||||
}
|
||||
@ -499,16 +499,7 @@ func getMaintainersImpl(kernelSrc, file string, blame bool) ([]string, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
lines := strings.Split(string(output), "\n")
|
||||
var mtrs []string
|
||||
for _, line := range lines {
|
||||
addr, err := mail.ParseAddress(line)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
mtrs = append(mtrs, addr.Address)
|
||||
}
|
||||
return mtrs, nil
|
||||
return vcs.ParseMaintainersLinux(output), nil
|
||||
}
|
||||
|
||||
func (ctx *linux) extractFiles(report []byte) []string {
|
||||
|
@ -13,6 +13,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/google/syzkaller/pkg/mgrconfig"
|
||||
"github.com/google/syzkaller/pkg/vcs"
|
||||
"github.com/google/syzkaller/sys/targets"
|
||||
)
|
||||
|
||||
@ -50,8 +51,8 @@ type Report struct {
|
||||
Corrupted bool
|
||||
// CorruptedReason contains reason why the report is marked as corrupted.
|
||||
CorruptedReason string
|
||||
// Maintainers is list of maintainer emails (filled in by Symbolize).
|
||||
Maintainers []string
|
||||
// Recipients is a list of RecipientInfo with Email, Display Name, and type.
|
||||
Recipients vcs.Recipients
|
||||
// guiltyFile is the source file that we think is to blame for the crash (filled in by Symbolize).
|
||||
guiltyFile string
|
||||
// reportPrefixLen is length of additional prefix lines that we added before actual crash report.
|
||||
|
@ -196,8 +196,8 @@ func gitParseCommit(output, user, domain []byte, ignoreCC map[string]bool) (*Com
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse date in git log output: %v\n%q", err, output)
|
||||
}
|
||||
cc := make(map[string]bool)
|
||||
cc[strings.ToLower(string(lines[2]))] = true
|
||||
recipients := make(map[string]bool)
|
||||
recipients[strings.ToLower(string(lines[2]))] = true
|
||||
var tags []string
|
||||
// Use summary line + all description lines.
|
||||
for _, line := range append([][]byte{lines[1]}, lines[6:]...) {
|
||||
@ -235,15 +235,15 @@ func gitParseCommit(output, user, domain []byte, ignoreCC map[string]bool) (*Com
|
||||
if ignoreCC[email] {
|
||||
continue
|
||||
}
|
||||
cc[email] = true
|
||||
recipients[email] = true
|
||||
break
|
||||
}
|
||||
}
|
||||
sortedCC := make([]string, 0, len(cc))
|
||||
for addr := range cc {
|
||||
sortedCC = append(sortedCC, addr)
|
||||
sortedRecipients := make(Recipients, 0, len(recipients))
|
||||
for addr := range recipients {
|
||||
sortedRecipients = append(sortedRecipients, RecipientInfo{mail.Address{Address: addr}, To})
|
||||
}
|
||||
sort.Strings(sortedCC)
|
||||
sort.Sort(sortedRecipients)
|
||||
parents := strings.Split(string(lines[5]), " ")
|
||||
com := &Commit{
|
||||
Hash: string(lines[0]),
|
||||
@ -251,7 +251,7 @@ func gitParseCommit(output, user, domain []byte, ignoreCC map[string]bool) (*Com
|
||||
Author: string(lines[2]),
|
||||
AuthorName: string(lines[3]),
|
||||
Parents: parents,
|
||||
CC: sortedCC,
|
||||
Recipients: sortedRecipients,
|
||||
Tags: tags,
|
||||
Date: date,
|
||||
}
|
||||
|
@ -167,8 +167,8 @@ func checkCommit(t *testing.T, idx int, test testCommit, com *Commit, checkTags
|
||||
if userName != com.AuthorName {
|
||||
t.Errorf("#%v: want author name %q, got %q", idx, userName, com.Author)
|
||||
}
|
||||
if diff := cmp.Diff(test.cc, com.CC); diff != "" {
|
||||
t.Logf("%#v", com.CC)
|
||||
if diff := cmp.Diff(test.cc, com.Recipients.GetEmails(To)); diff != "" {
|
||||
t.Logf("%#v", com.Recipients)
|
||||
t.Error(diff)
|
||||
}
|
||||
if diff := cmp.Diff(test.tags, com.Tags); checkTags && diff != "" {
|
||||
|
@ -37,7 +37,7 @@ Signed-off-by: Linux Master <linux@linux-foundation.org>
|
||||
Title: "rbtree: include rcu.h",
|
||||
Author: "foobar@foobar.de",
|
||||
AuthorName: "Foo Bar",
|
||||
CC: []string{
|
||||
Recipients: NewRecipients([]string{
|
||||
"and@me.com",
|
||||
"another@email.de",
|
||||
"foobar@foobar.de",
|
||||
@ -46,7 +46,7 @@ Signed-off-by: Linux Master <linux@linux-foundation.org>
|
||||
"name@name.com",
|
||||
"subsystem@reviewer.com",
|
||||
"yetanother@email.org",
|
||||
},
|
||||
}, To),
|
||||
Date: time.Date(2018, 5, 11, 16, 02, 14, 0, time.FixedZone("", -7*60*60)),
|
||||
},
|
||||
}
|
||||
@ -70,7 +70,7 @@ Signed-off-by: Linux Master <linux@linux-foundation.org>
|
||||
if com.Author != res.Author {
|
||||
t.Fatalf("want author %q, got %q", com.Author, res.Author)
|
||||
}
|
||||
if diff := cmp.Diff(com.CC, res.CC); diff != "" {
|
||||
if diff := cmp.Diff(com.Recipients, res.Recipients); diff != "" {
|
||||
t.Fatalf("bad CC: %v", diff)
|
||||
}
|
||||
if !com.Date.Equal(res.Date) {
|
||||
|
@ -12,12 +12,12 @@ import (
|
||||
"net/mail"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/google/syzkaller/pkg/email"
|
||||
"github.com/google/syzkaller/pkg/osutil"
|
||||
"github.com/google/syzkaller/prog"
|
||||
)
|
||||
@ -214,21 +214,22 @@ func (ctx *linux) Bisect(bad, good string, trace io.Writer, pred func() (BisectR
|
||||
}
|
||||
|
||||
func (ctx *linux) addMaintainers(com *Commit) {
|
||||
if len(com.CC) > 2 {
|
||||
if len(com.Recipients) > 2 {
|
||||
return
|
||||
}
|
||||
list := ctx.getMaintainers(com.Hash, false)
|
||||
if len(list) < 3 {
|
||||
list = ctx.getMaintainers(com.Hash, true)
|
||||
mtrs := ctx.getMaintainers(com.Hash, false)
|
||||
if len(mtrs) < 3 {
|
||||
mtrs = ctx.getMaintainers(com.Hash, true)
|
||||
}
|
||||
com.CC = email.MergeEmailLists(com.CC, list)
|
||||
com.Recipients = append(com.Recipients, mtrs...)
|
||||
sort.Sort(com.Recipients)
|
||||
}
|
||||
|
||||
func (ctx *linux) getMaintainers(hash string, blame bool) []string {
|
||||
func (ctx *linux) getMaintainers(hash string, blame bool) Recipients {
|
||||
// See #1441 re --git-min-percent.
|
||||
args := "git show " + hash + " | " +
|
||||
filepath.FromSlash("scripts/get_maintainer.pl") +
|
||||
" --no-n --no-rolestats --git-min-percent=20"
|
||||
" --git-min-percent=20"
|
||||
if blame {
|
||||
args += " --git-blame"
|
||||
}
|
||||
@ -236,15 +237,42 @@ func (ctx *linux) getMaintainers(hash string, blame bool) []string {
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
var list []string
|
||||
for _, line := range strings.Split(string(output), "\n") {
|
||||
addr, err := mail.ParseAddress(line)
|
||||
return ParseMaintainersLinux(output)
|
||||
}
|
||||
|
||||
func ParseMaintainersLinux(text []byte) Recipients {
|
||||
lines := strings.Split(string(text), "\n")
|
||||
reRole := regexp.MustCompile(` \([^)]+\)$`)
|
||||
var mtrs Recipients
|
||||
// LMKL is To by default, but it changes to Cc if there's also a subsystem list.
|
||||
lkmlType := To
|
||||
foundLkml := false
|
||||
for _, line := range lines {
|
||||
role := reRole.FindString(line)
|
||||
address := strings.Replace(line, role, "", 1)
|
||||
addr, err := mail.ParseAddress(address)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
list = append(list, strings.ToLower(addr.Address))
|
||||
var roleType RecipientType
|
||||
if addr.Address == "linux-kernel@vger.kernel.org" {
|
||||
foundLkml = true
|
||||
continue
|
||||
} else if strings.Contains(role, "list") {
|
||||
lkmlType = Cc
|
||||
roleType = To
|
||||
} else if strings.Contains(role, "maintainer") || strings.Contains(role, "supporter") {
|
||||
roleType = To
|
||||
} else {
|
||||
roleType = Cc // Reviewer or other role; default to Cc.
|
||||
}
|
||||
mtrs = append(mtrs, RecipientInfo{*addr, roleType})
|
||||
}
|
||||
return list
|
||||
if foundLkml {
|
||||
mtrs = append(mtrs, RecipientInfo{mail.Address{Address: "linux-kernel@vger.kernel.org"}, lkmlType})
|
||||
}
|
||||
sort.Sort(mtrs)
|
||||
return mtrs
|
||||
}
|
||||
|
||||
const configBisectTag = "# Minimized by syzkaller"
|
||||
|
@ -8,13 +8,66 @@ import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/mail"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/google/syzkaller/dashboard/dashapi"
|
||||
"github.com/google/syzkaller/pkg/osutil"
|
||||
)
|
||||
|
||||
type RecipientType int
|
||||
|
||||
const (
|
||||
To RecipientType = iota
|
||||
Cc
|
||||
)
|
||||
|
||||
func (t RecipientType) String() string {
|
||||
return [...]string{"To", "Cc"}[t]
|
||||
}
|
||||
|
||||
type RecipientInfo struct {
|
||||
Address mail.Address
|
||||
Type RecipientType
|
||||
}
|
||||
|
||||
type Recipients []RecipientInfo
|
||||
|
||||
func (r Recipients) GetEmails(filter RecipientType) []string {
|
||||
emails := []string{}
|
||||
for _, user := range r {
|
||||
if user.Type == filter {
|
||||
emails = append(emails, user.Address.Address)
|
||||
}
|
||||
}
|
||||
sort.Strings(emails)
|
||||
return emails
|
||||
}
|
||||
|
||||
func NewRecipients(emails []string, t RecipientType) Recipients {
|
||||
r := Recipients{}
|
||||
for _, e := range emails {
|
||||
r = append(r, RecipientInfo{mail.Address{Address: e}, t})
|
||||
}
|
||||
sort.Sort(r)
|
||||
return r
|
||||
}
|
||||
|
||||
func (r Recipients) Len() int { return len(r) }
|
||||
func (r Recipients) Less(i, j int) bool { return r[i].Address.Address < r[j].Address.Address }
|
||||
func (r Recipients) Swap(i, j int) { r[i], r[j] = r[j], r[i] }
|
||||
|
||||
func (r Recipients) ToDash() dashapi.Recipients {
|
||||
d := dashapi.Recipients{}
|
||||
for _, user := range r {
|
||||
d = append(d, dashapi.RecipientInfo{Address: user.Address, Type: dashapi.RecipientType(user.Type)})
|
||||
}
|
||||
return d
|
||||
}
|
||||
|
||||
type Repo interface {
|
||||
// Poll checkouts the specified repository/branch.
|
||||
// This involves fetching/resetting/cloning as necessary to recover from all possible problems.
|
||||
@ -78,7 +131,7 @@ type Commit struct {
|
||||
Title string
|
||||
Author string
|
||||
AuthorName string
|
||||
CC []string
|
||||
Recipients Recipients
|
||||
Tags []string
|
||||
Parents []string
|
||||
Date time.Time
|
||||
|
@ -4,7 +4,10 @@
|
||||
package vcs
|
||||
|
||||
import (
|
||||
"net/mail"
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
)
|
||||
|
||||
func TestCanonicalizeCommit(t *testing.T) {
|
||||
@ -155,3 +158,37 @@ func TestCommitLink(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestParse(t *testing.T) {
|
||||
// nolint: lll
|
||||
test1 := []byte(`Foo (Maintainer) Bar <a@email.com> (maintainer:KERNEL)
|
||||
Foo Bar(Reviewer) <b@email.com> (reviewer:KERNEL)
|
||||
<somelist@list.com> (open list:FOO)
|
||||
"Supporter Foo" <c@email.com> (supporter:KERNEL)
|
||||
linux-kernel@vger.kernel.org (open list)`)
|
||||
// nolint: lll
|
||||
test2 := []byte(`Foo (Maintainer) Bar <a@email.com> (maintainer:KERNEL)
|
||||
Foo Bar(Reviewer) <b@email.com> (reviewer:KERNEL)
|
||||
"Supporter Foo" <c@email.com> (supporter:KERNEL)
|
||||
linux-kernel@vger.kernel.org (open list)`)
|
||||
|
||||
maintainers1 := Recipients{{mail.Address{Name: "Foo (Maintainer) Bar", Address: "a@email.com"}, To},
|
||||
{mail.Address{Name: "Foo Bar(Reviewer)", Address: "b@email.com"}, Cc},
|
||||
{mail.Address{Name: "Supporter Foo", Address: "c@email.com"}, To},
|
||||
{mail.Address{Name: "", Address: "linux-kernel@vger.kernel.org"}, Cc},
|
||||
{mail.Address{Name: "", Address: "somelist@list.com"}, To}}
|
||||
maintainers2 := Recipients{{mail.Address{Name: "Foo (Maintainer) Bar", Address: "a@email.com"}, To},
|
||||
{mail.Address{Name: "Foo Bar(Reviewer)", Address: "b@email.com"}, Cc},
|
||||
{mail.Address{Name: "Supporter Foo", Address: "c@email.com"}, To},
|
||||
{mail.Address{Name: "", Address: "linux-kernel@vger.kernel.org"}, To}}
|
||||
|
||||
if diff := cmp.Diff(ParseMaintainersLinux(test1), maintainers1); diff != "" {
|
||||
t.Fatal(diff)
|
||||
}
|
||||
if diff := cmp.Diff(ParseMaintainersLinux(test2), maintainers2); diff != "" {
|
||||
t.Fatal(diff)
|
||||
}
|
||||
if diff := cmp.Diff(ParseMaintainersLinux([]byte("")), Recipients(nil)); diff != "" {
|
||||
t.Fatal(diff)
|
||||
}
|
||||
}
|
||||
|
@ -438,7 +438,7 @@ func (jp *JobProcessor) bisect(job *Job, mgrcfg *mgrconfig.Config) error {
|
||||
Title: com.Title,
|
||||
Author: com.Author,
|
||||
AuthorName: com.AuthorName,
|
||||
CC: com.CC,
|
||||
Recipients: com.Recipients.ToDash(),
|
||||
Date: com.Date,
|
||||
})
|
||||
}
|
||||
@ -469,7 +469,7 @@ func (jp *JobProcessor) bisect(job *Job, mgrcfg *mgrconfig.Config) error {
|
||||
resp.CrashReport = res.Report.Report
|
||||
resp.CrashLog = res.Report.Output
|
||||
if len(resp.Commits) != 0 {
|
||||
resp.Commits[0].CC = append(resp.Commits[0].CC, res.Report.Maintainers...)
|
||||
resp.Commits[0].Recipients = append(resp.Commits[0].Recipients, res.Report.Recipients.ToDash()...)
|
||||
} else {
|
||||
// If there is a report and there is no commit, it means a crash
|
||||
// occurred on HEAD(for BisectFix) and oldest tested release(for BisectCause).
|
||||
|
@ -313,7 +313,7 @@ func (mgr *Manager) build(kernelCommit *vcs.Commit) error {
|
||||
case *build.KernelError:
|
||||
rep.Report = err1.Report
|
||||
rep.Output = err1.Output
|
||||
rep.Maintainers = err1.Maintainers
|
||||
rep.Recipients = err1.Recipients
|
||||
case *osutil.VerboseError:
|
||||
rep.Report = []byte(err1.Title)
|
||||
rep.Output = err1.Output
|
||||
@ -440,11 +440,11 @@ func (mgr *Manager) reportBuildError(rep *report.Report, info *BuildInfo, imageD
|
||||
req := &dashapi.BuildErrorReq{
|
||||
Build: *build,
|
||||
Crash: dashapi.Crash{
|
||||
Title: rep.Title,
|
||||
Corrupted: false, // Otherwise they get merged with other corrupted reports.
|
||||
Maintainers: rep.Maintainers,
|
||||
Log: rep.Output,
|
||||
Report: rep.Report,
|
||||
Title: rep.Title,
|
||||
Corrupted: false, // Otherwise they get merged with other corrupted reports.
|
||||
Recipients: rep.Recipients.ToDash(),
|
||||
Log: rep.Output,
|
||||
Report: rep.Report,
|
||||
},
|
||||
}
|
||||
return mgr.dash.ReportBuildError(req)
|
||||
|
@ -645,12 +645,12 @@ func (mgr *Manager) saveCrash(crash *Crash) bool {
|
||||
return true
|
||||
}
|
||||
dc := &dashapi.Crash{
|
||||
BuildID: mgr.cfg.Tag,
|
||||
Title: crash.Title,
|
||||
Corrupted: crash.Corrupted,
|
||||
Maintainers: crash.Maintainers,
|
||||
Log: crash.Output,
|
||||
Report: crash.Report.Report,
|
||||
BuildID: mgr.cfg.Tag,
|
||||
Title: crash.Title,
|
||||
Corrupted: crash.Corrupted,
|
||||
Recipients: crash.Recipients.ToDash(),
|
||||
Log: crash.Output,
|
||||
Report: crash.Report.Report,
|
||||
}
|
||||
resp, err := mgr.dash.ReportCrash(dc)
|
||||
if err != nil {
|
||||
@ -811,14 +811,14 @@ func (mgr *Manager) saveRepro(res *repro.Result, stats *repro.Stats, hub bool) {
|
||||
// so maybe corrupted report detection is broken.
|
||||
// 3. Reproduction is expensive so it's good to persist the result.
|
||||
dc := &dashapi.Crash{
|
||||
BuildID: mgr.cfg.Tag,
|
||||
Title: res.Report.Title,
|
||||
Maintainers: res.Report.Maintainers,
|
||||
Log: res.Report.Output,
|
||||
Report: res.Report.Report,
|
||||
ReproOpts: res.Opts.Serialize(),
|
||||
ReproSyz: res.Prog.Serialize(),
|
||||
ReproC: cprogText,
|
||||
BuildID: mgr.cfg.Tag,
|
||||
Title: res.Report.Title,
|
||||
Recipients: res.Report.Recipients.ToDash(),
|
||||
Log: res.Report.Output,
|
||||
Report: res.Report.Report,
|
||||
ReproOpts: res.Opts.Serialize(),
|
||||
ReproSyz: res.Prog.Serialize(),
|
||||
ReproC: cprogText,
|
||||
}
|
||||
if _, err := mgr.dash.ReportCrash(dc); err != nil {
|
||||
log.Logf(0, "failed to report repro to dashboard: %v", err)
|
||||
|
@ -15,6 +15,7 @@ import (
|
||||
"github.com/google/syzkaller/pkg/mgrconfig"
|
||||
"github.com/google/syzkaller/pkg/osutil"
|
||||
"github.com/google/syzkaller/pkg/report"
|
||||
"github.com/google/syzkaller/pkg/vcs"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -69,7 +70,8 @@ func main() {
|
||||
}
|
||||
fmt.Printf("TITLE: %v\n", rep.Title)
|
||||
fmt.Printf("CORRUPTED: %v (%v)\n", rep.Corrupted, rep.CorruptedReason)
|
||||
fmt.Printf("MAINTAINERS: %v\n", rep.Maintainers)
|
||||
fmt.Printf("MAINTAINERS (TO): %v\n", rep.Recipients.GetEmails(vcs.To))
|
||||
fmt.Printf("MAINTAINERS (CC): %v\n", rep.Recipients.GetEmails(vcs.Cc))
|
||||
fmt.Printf("\n")
|
||||
os.Stdout.Write(rep.Report)
|
||||
fmt.Printf("\n\n")
|
||||
|
Loading…
Reference in New Issue
Block a user