Skip to content

Commit 003ba11

Browse files
committed
pkg/report: get only the thread local reports
After this change we'll see only the reports coming from the same thread.
1 parent 96a211b commit 003ba11

File tree

9 files changed

+2193
-172
lines changed

9 files changed

+2193
-172
lines changed

pkg/report/linux.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,8 +165,9 @@ func (ctx *linux) Parse(output []byte) *Report {
165165
}
166166
for questionable := false; ; questionable = true {
167167
rep := &Report{
168-
Output: output,
169-
StartPos: startPos,
168+
Output: output,
169+
StartPos: startPos,
170+
ContextID: context,
170171
}
171172
endPos, reportEnd, report, prefix := ctx.findReport(output, oops, startPos, context, questionable)
172173
rep.EndPos = endPos

pkg/report/report.go

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,10 @@ type Report struct {
7272
MachineInfo []byte
7373
// If the crash happened in the context of the syz-executor process, Executor will hold more info.
7474
Executor *ExecutorInfo
75+
// On Linux systems ContextID may be the ThreadID(enabled by CONFIG_PRINTK_CALLER)
76+
// or alternatively CpuID.
77+
ContextID string
78+
7579
// reportPrefixLen is length of additional prefix lines that we added before actual crash report.
7680
reportPrefixLen int
7781
// symbolized is set if the report is symbolized. It prevents double symbolization.
@@ -277,9 +281,9 @@ func IsSuppressed(reporter *Reporter, output []byte) bool {
277281
bytes.Contains(output, gceConsoleHangup)
278282
}
279283

280-
// ParseAll returns all successive reports in output.
281-
func ParseAll(reporter *Reporter, output []byte) (reports []*Report) {
282-
skipPos := 0
284+
// ParseAll returns all successive reports in output starting from startFrom.
285+
func ParseAll(reporter *Reporter, output []byte, startFrom int) (reports []*Report) {
286+
skipPos := startFrom
283287
for {
284288
rep := reporter.ParseFrom(output, skipPos)
285289
if rep == nil {
@@ -958,3 +962,11 @@ func MergeReportBytes(reps []*Report) []byte {
958962
func SplitReportBytes(data []byte) [][]byte {
959963
return bytes.Split(data, []byte(reportSeparator))
960964
}
965+
966+
func mergeReportContextIDs(reps []*Report) string {
967+
var ids []string
968+
for _, rep := range reps {
969+
ids = append(ids, rep.ContextID)
970+
}
971+
return strings.Join(ids, ", ")
972+
}

pkg/report/report_test.go

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ type ParseTest struct {
4444
HasReport bool
4545
Report []byte
4646
Executor string
47+
ContextIDs string
4748
// Only used in report parsing:
4849
corruptedReason string
4950
}
@@ -88,6 +89,9 @@ func (test *ParseTest) Headers(includeFrame bool) []byte {
8889
if test.Executor != "" {
8990
fmt.Fprintf(buf, "EXECUTOR: %s\n", test.Executor)
9091
}
92+
if test.ContextIDs != "" {
93+
fmt.Fprintf(buf, "CONTEXTS: %s\n", test.ContextIDs)
94+
}
9195
return buf.Bytes()
9296
}
9397

@@ -96,8 +100,8 @@ func testParseFile(t *testing.T, reporter *Reporter, fn string) {
96100
testParseImpl(t, reporter, test)
97101
}
98102

99-
func parseReport(t *testing.T, reporter *Reporter, fn string) *ParseTest {
100-
data, err := os.ReadFile(fn)
103+
func parseReport(t *testing.T, reporter *Reporter, testFileName string) *ParseTest {
104+
data, err := os.ReadFile(testFileName)
101105
if err != nil {
102106
t.Fatal(err)
103107
}
@@ -110,7 +114,7 @@ func parseReport(t *testing.T, reporter *Reporter, fn string) *ParseTest {
110114
)
111115
phase := phaseHeaders
112116
test := &ParseTest{
113-
FileName: fn,
117+
FileName: testFileName,
114118
}
115119
prevEmptyLine := false
116120
s := bufio.NewScanner(bytes.NewReader(data))
@@ -158,6 +162,7 @@ func parseHeaderLine(t *testing.T, test *ParseTest, ln string) {
158162
corruptedPrefix = "CORRUPTED: "
159163
suppressedPrefix = "SUPPRESSED: "
160164
executorPrefix = "EXECUTOR: "
165+
contextidPrefix = "CONTEXTS: "
161166
)
162167
switch {
163168
case strings.HasPrefix(ln, "#"):
@@ -193,6 +198,8 @@ func parseHeaderLine(t *testing.T, test *ParseTest, ln string) {
193198
}
194199
case strings.HasPrefix(ln, executorPrefix):
195200
test.Executor = ln[len(executorPrefix):]
201+
case strings.HasPrefix(ln, contextidPrefix):
202+
test.ContextIDs = ln[len(contextidPrefix):]
196203
default:
197204
t.Fatalf("unknown header field %q", ln)
198205
}
@@ -545,3 +552,26 @@ func TestSplitReportBytes(t *testing.T) {
545552
})
546553
}
547554
}
555+
556+
// TestParseAll's focus points are the ability to:
557+
// 1. parse multiple reports
558+
// 2. extract correct ThreadID/CpuID.
559+
func TestParseAll(t *testing.T) {
560+
forEachFile(t, "parse_all", testParseAll)
561+
}
562+
563+
func testParseAll(t *testing.T, reporter *Reporter, testFileName string) {
564+
test := parseReport(t, reporter, testFileName)
565+
gotReports := ParseAll(reporter, test.Log, 0)
566+
gotIDs := mergeReportContextIDs(gotReports)
567+
mergedReport := MergeReportBytes(gotReports)
568+
if !bytes.Equal(mergedReport, test.Report) || gotIDs != test.ContextIDs {
569+
if *flagUpdate {
570+
updateReportTest(t, test, &ParseTest{
571+
ContextIDs: gotIDs,
572+
Report: mergedReport})
573+
}
574+
assert.Equal(t, test.ContextIDs, gotIDs, "extracted wrong Thread or CPU ids")
575+
assert.Equal(t, string(test.Report), string(mergedReport), "extracted wrong reports")
576+
}
577+
}

pkg/report/testdata/linux/parse_all/1

Lines changed: 836 additions & 0 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)