1// Copyright 2015 syzkaller project authors. All rights reserved. 2// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. 3 4package main 5 6import ( 7 "flag" 8 "fmt" 9 "io/ioutil" 10 "os" 11 12 "github.com/google/syzkaller/pkg/csource" 13 "github.com/google/syzkaller/pkg/log" 14 "github.com/google/syzkaller/pkg/mgrconfig" 15 "github.com/google/syzkaller/pkg/osutil" 16 "github.com/google/syzkaller/pkg/report" 17 "github.com/google/syzkaller/pkg/repro" 18 "github.com/google/syzkaller/prog" 19 "github.com/google/syzkaller/vm" 20) 21 22var ( 23 flagConfig = flag.String("config", "", "configuration file") 24 flagCount = flag.Int("count", 0, "number of VMs to use (overrides config count param)") 25 flagDebug = flag.Bool("debug", false, "print debug output") 26) 27 28func main() { 29 os.Args = append(append([]string{}, os.Args[0], "-v=10"), os.Args[1:]...) 30 flag.Parse() 31 cfg, err := mgrconfig.LoadFile(*flagConfig) 32 if err != nil { 33 log.Fatalf("%v", err) 34 } 35 if len(flag.Args()) != 1 { 36 log.Fatalf("usage: syz-repro -config=config.file execution.log") 37 } 38 data, err := ioutil.ReadFile(flag.Args()[0]) 39 if err != nil { 40 log.Fatalf("failed to open log file: %v", err) 41 } 42 if _, err := prog.GetTarget(cfg.TargetOS, cfg.TargetArch); err != nil { 43 log.Fatalf("%v", err) 44 } 45 vmPool, err := vm.Create(cfg, *flagDebug) 46 if err != nil { 47 log.Fatalf("%v", err) 48 } 49 vmCount := vmPool.Count() 50 if *flagCount > 0 && *flagCount < vmCount { 51 vmCount = *flagCount 52 } 53 if vmCount > 4 { 54 vmCount = 4 55 } 56 vmIndexes := make([]int, vmCount) 57 for i := range vmIndexes { 58 vmIndexes[i] = i 59 } 60 reporter, err := report.NewReporter(cfg) 61 if err != nil { 62 log.Fatalf("%v", err) 63 } 64 osutil.HandleInterrupts(vm.Shutdown) 65 66 res, stats, err := repro.Run(data, cfg, reporter, vmPool, vmIndexes) 67 if err != nil { 68 log.Logf(0, "reproduction failed: %v", err) 69 } 70 if stats != nil { 71 fmt.Printf("Extracting prog: %v\n", stats.ExtractProgTime) 72 fmt.Printf("Minimizing prog: %v\n", stats.MinimizeProgTime) 73 fmt.Printf("Simplifying prog options: %v\n", stats.SimplifyProgTime) 74 fmt.Printf("Extracting C: %v\n", stats.ExtractCTime) 75 fmt.Printf("Simplifying C: %v\n", stats.SimplifyCTime) 76 } 77 if res == nil { 78 return 79 } 80 81 fmt.Printf("opts: %+v crepro: %v\n\n", res.Opts, res.CRepro) 82 fmt.Printf("%s\n", res.Prog.Serialize()) 83 if res.CRepro { 84 src, err := csource.Write(res.Prog, res.Opts) 85 if err != nil { 86 log.Fatalf("failed to generate C repro: %v", err) 87 } 88 if formatted, err := csource.Format(src); err == nil { 89 src = formatted 90 } 91 fmt.Printf("%s\n", src) 92 } 93} 94