mirror of
https://github.com/reactos/syzkaller.git
synced 2024-11-25 04:19:53 +00:00
185 lines
3.9 KiB
Go
185 lines
3.9 KiB
Go
// Copyright 2016 syzkaller project authors. All rights reserved.
|
|
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
|
|
|
|
package symbolizer
|
|
|
|
import (
|
|
"bufio"
|
|
"os"
|
|
"reflect"
|
|
"strconv"
|
|
"testing"
|
|
)
|
|
|
|
func TestParse(t *testing.T) {
|
|
addresses := []struct {
|
|
pc uint64
|
|
resp string
|
|
frames []Frame
|
|
}{
|
|
{
|
|
0xffffffff8180a42e,
|
|
"0xffffffff8180a42e\n" +
|
|
"__asan_report_load2_noabort\n" +
|
|
"mm/kasan/report.c:320\n",
|
|
[]Frame{
|
|
Frame{
|
|
PC: 0xffffffff8180a42e,
|
|
Func: "__asan_report_load2_noabort",
|
|
File: "mm/kasan/report.c",
|
|
Line: 320,
|
|
Inline: false,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
0xffffffff8180a42d,
|
|
"0xffffffff8180a42d\n" +
|
|
"kasan_report\n" +
|
|
"mm/kasan/report.c:301\n" +
|
|
"__asan_report_load2_noabort\n" +
|
|
"mm/kasan/report.c:320\n",
|
|
[]Frame{
|
|
Frame{
|
|
PC: 0xffffffff8180a42d,
|
|
Func: "kasan_report",
|
|
File: "mm/kasan/report.c",
|
|
Line: 301,
|
|
Inline: true,
|
|
},
|
|
Frame{
|
|
PC: 0xffffffff8180a42d,
|
|
Func: "__asan_report_load2_noabort",
|
|
File: "mm/kasan/report.c",
|
|
Line: 320,
|
|
Inline: false,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
0xffffffff82fdbe0b,
|
|
"0xffffffff82fdbe0b\n" +
|
|
"fbcon_invert_region\n" +
|
|
"drivers/video/console/fbcon.c:2750\n",
|
|
[]Frame{
|
|
Frame{
|
|
PC: 0xffffffff82fdbe0b,
|
|
Func: "fbcon_invert_region",
|
|
File: "drivers/video/console/fbcon.c",
|
|
Line: 2750,
|
|
Inline: false,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
0x123124,
|
|
"0x0000000000123124\n" +
|
|
"??\n" +
|
|
"??:0\n",
|
|
nil,
|
|
},
|
|
{
|
|
0xffffffffffffffff,
|
|
"0xffffffffffffffff\n" +
|
|
"??\n" +
|
|
"??:0\n",
|
|
nil,
|
|
},
|
|
{
|
|
0xffffffff81a2aff9,
|
|
"0xffffffff81a2aff9\n" +
|
|
"devpts_get_priv\n" +
|
|
"fs/devpts/inode.c:588 (discriminator 3)\n",
|
|
[]Frame{
|
|
Frame{
|
|
PC: 0xffffffff81a2aff9,
|
|
Func: "devpts_get_priv",
|
|
File: "fs/devpts/inode.c",
|
|
Line: 588,
|
|
Inline: false,
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
// Stub addr2line.
|
|
inputr, inputw, err := os.Pipe()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer inputr.Close()
|
|
defer inputw.Close()
|
|
outputr, outputw, err := os.Pipe()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer outputr.Close()
|
|
go func() {
|
|
s := bufio.NewScanner(inputr)
|
|
loop:
|
|
for s.Scan() {
|
|
pc, err := strconv.ParseUint(s.Text(), 0, 64)
|
|
if err != nil {
|
|
outputw.Close()
|
|
t.Fatalf("got unexpected pc: %v", s.Text())
|
|
}
|
|
for _, addr := range addresses {
|
|
if pc == addr.pc {
|
|
outputw.Write([]byte(addr.resp))
|
|
continue loop
|
|
}
|
|
}
|
|
outputw.Close()
|
|
t.Fatalf("got unexpected pc: 0x%x", pc)
|
|
}
|
|
outputw.Write([]byte("DONE\n"))
|
|
outputw.Close()
|
|
}()
|
|
|
|
// First, symbolize all PCs one-by-one.
|
|
input := bufio.NewWriter(inputw)
|
|
scanner := bufio.NewScanner(outputr)
|
|
var allPCs []uint64
|
|
var allFrames []Frame
|
|
for _, addr := range addresses {
|
|
frames, err := symbolize(input, scanner, []uint64{addr.pc})
|
|
if err != nil {
|
|
t.Fatalf("got error: %v", err)
|
|
}
|
|
if !reflect.DeepEqual(addr.frames, frames) {
|
|
t.Fatalf("want frames:\n%+v\ngot:\n%+v\n", addr.frames, frames)
|
|
}
|
|
allPCs = append(allPCs, addr.pc)
|
|
allFrames = append(allFrames, frames...)
|
|
}
|
|
|
|
// Symbolize PCs in 2 groups.
|
|
for i := 0; i <= len(addresses); i++ {
|
|
frames, err := symbolize(input, scanner, allPCs[:i])
|
|
if err != nil {
|
|
t.Fatalf("got error: %v", err)
|
|
}
|
|
frames2, err := symbolize(input, scanner, allPCs[i:])
|
|
if err != nil {
|
|
t.Fatalf("got error: %v", err)
|
|
}
|
|
frames = append(frames, frames2...)
|
|
if !reflect.DeepEqual(allFrames, frames) {
|
|
t.Fatalf("want frames:\n%+v\ngot:\n%+v\n", allFrames, frames)
|
|
}
|
|
}
|
|
|
|
// Symbolize a huge pile of PCs (test for pipe overflows).
|
|
lots := make([]uint64, 1e4)
|
|
for i := range lots {
|
|
lots[i] = addresses[0].pc
|
|
}
|
|
frames, err := symbolize(input, scanner, lots)
|
|
if err != nil {
|
|
t.Fatalf("got error: %v", err)
|
|
}
|
|
if want := len(lots) * len(addresses[0].frames); want != len(frames) {
|
|
t.Fatalf("want %v frames, got %v", want, len(frames))
|
|
}
|
|
}
|