func execute(pid int, env *ipc.Env, p *prog.Prog) { if *flagExecutor == "" { return } atomic.AddUint64(&statExec, 1) if *flagLogProg { ticket := gate.Enter() defer gate.Leave(ticket) outMu.Lock() fmt.Printf("executing program %v\n%s\n", pid, p.Serialize()) outMu.Unlock() } output, _, _, failed, hanged, err := env.Exec(p) if err != nil { fmt.Printf("failed to execute executor: %v\n", err) } paniced := failedRe.Match(output) if failed || hanged || paniced || err != nil { fmt.Printf("PROGRAM:\n%s\n", p.Serialize()) } if failed || hanged || paniced || err != nil || *flagOutput { os.Stdout.Write(output) } }
func execute(env *ipc.Env, p *prog.Prog) { if *flagExecutor == "" { return } output, _, _, _, _, err := env.Exec(p) if err != nil { fmt.Printf("failed to execute executor: %v\n", err) } failed := failedRe.Match(output) if failed { fmt.Printf("PROGRAM:\n%s\n", p.Serialize()) } if failed || *flagOutput { os.Stdout.Write(output) } }
func execute1(env *ipc.Env, p *prog.Prog, stat *uint64) []cover.Cover { if *flagSaveProg { f, err := os.Create(fmt.Sprintf("%v.prog", *flagName)) if err == nil { f.Write(p.Serialize()) f.Close() } } else { // The following output helps to understand what program crashed kernel. // It must not be intermixed. logMu.Lock() log.Printf("executing program:\n%s", p.Serialize()) logMu.Unlock() } try := 0 retry: *stat++ output, strace, rawCover, failed, hanged, err := env.Exec(p) if err != nil { if try > 10 { panic(err) } try++ debug.FreeOSMemory() time.Sleep(time.Second) goto retry } logf(4, "result failed=%v hanged=%v:\n%v\n", failed, hanged, string(output)) if len(strace) != 0 { logf(4, "strace:\n%s\n", strace) } cov := make([]cover.Cover, len(p.Calls)) for i, c := range rawCover { cov[i] = cover.Cover(c) } return cov }
func execute1(pid int, env *ipc.Env, p *prog.Prog, stat *uint64) []cover.Cover { if false { // For debugging, this function must not be executed with locks held. corpusMu.Lock() corpusMu.Unlock() coverMu.Lock() coverMu.Unlock() triageMu.Lock() triageMu.Unlock() } // Limit concurrency window and do leak checking once in a while. idx := gate.Enter() defer gate.Leave(idx, func() { if idx == 0 && *flagLeak && atomic.LoadUint32(&allTriaged) != 0 { // Scan for leaks once in a while (it is damn slow). kmemleakScan(true) } }) // The following output helps to understand what program crashed kernel. // It must not be intermixed. switch *flagOutput { case "none": // This case intentionally left blank. case "stdout": data := p.Serialize() logMu.Lock() log.Printf("executing program %v:\n%s", pid, data) logMu.Unlock() case "dmesg": fd, err := syscall.Open("/dev/kmsg", syscall.O_WRONLY, 0) if err == nil { buf := new(bytes.Buffer) fmt.Fprintf(buf, "syzkaller: executing program %v:\n%s", pid, p.Serialize()) syscall.Write(fd, buf.Bytes()) syscall.Close(fd) } case "file": f, err := os.Create(fmt.Sprintf("%v-%v.prog", *flagName, pid)) if err == nil { f.Write(p.Serialize()) f.Close() } } try := 0 retry: atomic.AddUint64(stat, 1) output, rawCover, errnos, failed, hanged, err := env.Exec(p) _ = errnos if failed { // BUG in output should be recognized by manager. logf(0, "BUG: executor-detected bug:\n%s", output) // Don't return any cover so that the input is not added to corpus. return make([]cover.Cover, len(p.Calls)) } if err != nil { if try > 10 { panic(err) } try++ debug.FreeOSMemory() time.Sleep(time.Second) goto retry } logf(4, "result failed=%v hanged=%v:\n%v\n", failed, hanged, string(output)) cov := make([]cover.Cover, len(p.Calls)) for i, c := range rawCover { cov[i] = cover.Cover(c) } return cov }