Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 package main | 1 package main |
| 2 | 2 |
| 3 /* | 3 /* |
| 4 Runs the backend portions of the fuzzer. This includes the generator and aggreg ator parts (see DESIGN.md) | 4 Runs the backend portions of the fuzzer. This includes the generator and aggreg ator parts (see DESIGN.md) |
| 5 */ | 5 */ |
| 6 | 6 |
| 7 import ( | 7 import ( |
| 8 "flag" | 8 "flag" |
| 9 "fmt" | 9 "fmt" |
| 10 "os" | 10 "os" |
| 11 "path/filepath" | 11 "path/filepath" |
| 12 "time" | 12 "time" |
| 13 | 13 |
| 14 "github.com/skia-dev/glog" | 14 "github.com/skia-dev/glog" |
| 15 "go.skia.org/infra/fuzzer/go/aggregator" | 15 "go.skia.org/infra/fuzzer/go/aggregator" |
| 16 "go.skia.org/infra/fuzzer/go/backend" | 16 "go.skia.org/infra/fuzzer/go/backend" |
| 17 fcommon "go.skia.org/infra/fuzzer/go/common" | 17 fcommon "go.skia.org/infra/fuzzer/go/common" |
| 18 "go.skia.org/infra/fuzzer/go/config" | 18 "go.skia.org/infra/fuzzer/go/config" |
| 19 "go.skia.org/infra/fuzzer/go/generator" | 19 "go.skia.org/infra/fuzzer/go/generator" |
| 20 "go.skia.org/infra/go/auth" | 20 "go.skia.org/infra/go/auth" |
| 21 "go.skia.org/infra/go/common" | 21 "go.skia.org/infra/go/common" |
| 22 "go.skia.org/infra/go/fileutil" | 22 "go.skia.org/infra/go/fileutil" |
| 23 "go.skia.org/infra/go/influxdb" | |
| 23 "golang.org/x/net/context" | 24 "golang.org/x/net/context" |
| 24 "google.golang.org/cloud" | 25 "google.golang.org/cloud" |
| 25 "google.golang.org/cloud/storage" | 26 "google.golang.org/cloud/storage" |
| 26 ) | 27 ) |
| 27 | 28 |
| 28 var ( | 29 var ( |
| 29 aflOutputPath = flag.String("afl_output_path", "", "[REQUIRED] The output folder of afl-fuzz. This will have on folder for each fuzz_to_run. Each of those will have N folders named fuzzer0 - fuzzerN. Should not be in /tmp or afl-fuzz will refuse to run.") | 30 aflOutputPath = flag.String("afl_output_path", "", "[REQUIRED] The output folder of afl-fuzz. This will have on folder for each fuzz_to_run. Each of those will have N folders named fuzzer0 - fuzzerN. Should not be in /tmp or afl-fuzz will refuse to run.") |
| 30 generatorWD = flag.String("generator_working_dir", "", "[REQUIRED ] The generator's working directory. Should not be in /tmp.") | 31 generatorWD = flag.String("generator_working_dir", "", "[REQUIRED ] The generator's working directory. Should not be in /tmp.") |
| 31 fuzzSamples = flag.String("fuzz_samples", "", "[REQUIRED] The gen erator's working directory. Should not be in /tmp.") | 32 fuzzSamples = flag.String("fuzz_samples", "", "[REQUIRED] The gen erator's working directory. Should not be in /tmp.") |
| 32 skiaRoot = flag.String("skia_root", "", "[REQUIRED] The root d irectory of the Skia source code.") | 33 skiaRoot = flag.String("skia_root", "", "[REQUIRED] The root d irectory of the Skia source code.") |
| 33 clangPath = flag.String("clang_path", "", "[REQUIRED] The path to the clang executable.") | 34 clangPath = flag.String("clang_path", "", "[REQUIRED] The path to the clang executable.") |
| 34 clangPlusPlusPath = flag.String("clang_p_p_path", "", "[REQUIRED] The p ath to the clang++ executable.") | 35 clangPlusPlusPath = flag.String("clang_p_p_path", "", "[REQUIRED] The p ath to the clang++ executable.") |
| 35 depotToolsPath = flag.String("depot_tools_path", "", "The absolute p ath to depot_tools. Can be empty if they are on your path.") | 36 depotToolsPath = flag.String("depot_tools_path", "", "The absolute p ath to depot_tools. Can be empty if they are on your path.") |
| 36 aflRoot = flag.String("afl_root", "", "[REQUIRED] The install directory of afl-fuzz (v1.94b or later).") | 37 aflRoot = flag.String("afl_root", "", "[REQUIRED] The install directory of afl-fuzz (v1.94b or later).") |
| 37 numFuzzProcesses = flag.Int("fuzz_processes", 0, `The number of proces ses to run afl-fuzz [per fuzz to run]. This should be fewer than the number of logical cores. Defaults to 0, which means "Make an intelligent guess"`) | 38 numFuzzProcesses = flag.Int("fuzz_processes", 0, `The number of proces ses to run afl-fuzz [per fuzz to run]. This should be fewer than the number of logical cores. Defaults to 0, which means "Make an intelligent guess"`) |
| 38 versionCheckPeriod = flag.Duration("version_check_period", 20*time.Secon d, `The period used to check the version of Skia that needs fuzzing.`) | 39 versionCheckPeriod = flag.Duration("version_check_period", 20*time.Secon d, `The period used to check the version of Skia that needs fuzzing.`) |
| 39 downloadProcesses = flag.Int("download_processes", 4, "The number of do wnload processes to be used for fetching fuzzes when re-analyzing them. This is constant with respect to the number of fuzzes.") | 40 downloadProcesses = flag.Int("download_processes", 4, "The number of do wnload processes to be used for fetching fuzzes when re-analyzing them. This is constant with respect to the number of fuzzes.") |
| 40 fuzzesToRun = common.NewMultiStringFlag("fuzz_to_run", nil, fmt.S printf("A set of fuzzes to run. Can be one or more of the known fuzzes: %q", fc ommon.FUZZ_CATEGORIES)) | 41 fuzzesToRun = common.NewMultiStringFlag("fuzz_to_run", nil, fmt.S printf("A set of fuzzes to run. Can be one or more of the known fuzzes: %q", fc ommon.FUZZ_CATEGORIES)) |
| 41 | 42 |
| 42 bucket = flag.String("bucket", "skia-fuzzer", "The GCS buc ket in which to store found fuzzes.") | 43 bucket = flag.String("bucket", "skia-fuzzer", "The GCS buc ket in which to store found fuzzes.") |
| 43 fuzzPath = flag.String("fuzz_path", filepath.Join(os.TempDir (), "fuzzes"), "The directory to temporarily store the binary fuzzes during aggr egation.") | 44 fuzzPath = flag.String("fuzz_path", filepath.Join(os.TempDir (), "fuzzes"), "The directory to temporarily store the binary fuzzes during aggr egation.") |
| 44 executablePath = flag.String("executable_path", filepath.Join(os.T empDir(), "executables"), "The directory to store temporary executables that wil l run the fuzzes during aggregation. Defaults to /tmp/executables.") | 45 executablePath = flag.String("executable_path", filepath.Join(os.T empDir(), "executables"), "The directory to store temporary executables that wil l run the fuzzes during aggregation. Defaults to /tmp/executables.") |
| 45 numAnalysisProcesses = flag.Int("analysis_processes", 0, `The number of processes to analyze fuzzes [per fuzz to run]. This should be fewer than the nu mber of logical cores. Defaults to 0, which means "Make an intelligent guess"`) | 46 numAnalysisProcesses = flag.Int("analysis_processes", 0, `The number of processes to analyze fuzzes [per fuzz to run]. This should be fewer than the nu mber of logical cores. Defaults to 0, which means "Make an intelligent guess"`) |
| 46 rescanPeriod = flag.Duration("rescan_period", 60*time.Second, `T he time in which to sleep for every cycle of aggregation. `) | 47 rescanPeriod = flag.Duration("rescan_period", 60*time.Second, `T he time in which to sleep for every cycle of aggregation. `) |
| 47 numUploadProcesses = flag.Int("upload_processes", 0, `The number of pr ocesses to upload fuzzes [per fuzz to run]. Defaults to 0, which means "Make an intelligent guess"`) | 48 numUploadProcesses = flag.Int("upload_processes", 0, `The number of pr ocesses to upload fuzzes [per fuzz to run]. Defaults to 0, which means "Make an intelligent guess"`) |
| 48 statusPeriod = flag.Duration("status_period", 60*time.Second, `T he time period used to report the status of the aggregation/analysis/upload queu e. `) | 49 statusPeriod = flag.Duration("status_period", 60*time.Second, `T he time period used to report the status of the aggregation/analysis/upload queu e. `) |
| 49 analysisTimeout = flag.Duration("analysis_timeout", 5*time.Second, `The maximum time an analysis should run.`) | 50 analysisTimeout = flag.Duration("analysis_timeout", 5*time.Second, `The maximum time an analysis should run.`) |
| 50 | 51 |
| 51 » graphiteServer = flag.String("graphite_server", "localhost:2003", "Where is Graphite metrics ingestion server running.") | 52 » influxHost = flag.String("influxdb_host", influxdb.DEFAULT_HOST, "Th e InfluxDB hostname.") |
| 53 » influxUser = flag.String("influxdb_name", influxdb.DEFAULT_USER, "Th e InfluxDB username.") | |
| 54 » influxPassword = flag.String("influxdb_password", influxdb.DEFAULT_PASSW ORD, "The InfluxDB password.") | |
| 55 » influxDatabase = flag.String("influxdb_database", influxdb.DEFAULT_DATAB ASE, "The InfluxDB database.") | |
| 52 | 56 |
| 53 watchAFL = flag.Bool("watch_afl", false, "(debug only) If the afl master's output should be piped to stdout.") | 57 watchAFL = flag.Bool("watch_afl", false, "(debug only) If the afl master's output should be piped to stdout.") |
| 54 skipGeneration = flag.Bool("skip_generation", false, "(debug only) If t he generation step should be disabled.") | 58 skipGeneration = flag.Bool("skip_generation", false, "(debug only) If t he generation step should be disabled.") |
| 55 » forceReanalysis = flag.Bool("force_reanalysis", false, "(debug only) If the fuzzes should be downloaded, re-analyzed, (deleted for GCS), and reuploaded. ") | 59 » forceReanalysis = flag.Bool("force_reanalysis", false, "(debug only) If the fuzzes should be downloaded, re-analyzed, (deleted from GCS), and reuploaded .") |
| 56 verboseBuilds = flag.Bool("verbose_builds", false, "If output from nin ja and gyp should be printed to stdout.") | 60 verboseBuilds = flag.Bool("verbose_builds", false, "If output from nin ja and gyp should be printed to stdout.") |
| 61 local = flag.Bool("local", false, "Running locally if true. As opposed to in production.") | |
| 57 ) | 62 ) |
| 58 | 63 |
| 59 var ( | 64 var ( |
| 60 requiredFlags = []string{"afl_output_path", "skia_root", "clang_path", "clang_p_p_path", "afl_root", "generator_working_dir", "fuzz_to_r un"} | 65 requiredFlags = []string{"afl_output_path", "skia_root", "clang_path", "clang_p_p_path", "afl_root", "generator_working_dir", "fuzz_to_r un"} |
| 61 storageClient *storage.Client = nil | 66 storageClient *storage.Client = nil |
| 62 ) | 67 ) |
| 63 | 68 |
| 64 func main() { | 69 func main() { |
| 65 defer common.LogPanic() | 70 defer common.LogPanic() |
| 66 // Calls flag.Parse() | 71 // Calls flag.Parse() |
| 67 » common.InitWithMetrics("fuzzer-be", graphiteServer) | 72 » common.InitWithMetrics2("fuzzer-be", influxHost, influxUser, influxPassw ord, influxDatabase, local) |
| 68 | 73 |
| 69 if err := writeFlagsToConfig(); err != nil { | 74 if err := writeFlagsToConfig(); err != nil { |
| 70 glog.Fatalf("Problem with configuration: %v", err) | 75 glog.Fatalf("Problem with configuration: %v", err) |
| 71 } | 76 } |
| 72 if err := setupOAuth(); err != nil { | 77 if err := setupOAuth(); err != nil { |
| 73 glog.Fatalf("Problem with OAuth: %s", err) | 78 glog.Fatalf("Problem with OAuth: %s", err) |
| 74 } | 79 } |
| 75 if err := fcommon.DownloadSkiaVersionForFuzzing(storageClient, config.Ge nerator.SkiaRoot, &config.Generator); err != nil { | 80 if err := fcommon.DownloadSkiaVersionForFuzzing(storageClient, config.Ge nerator.SkiaRoot, &config.Generator); err != nil { |
| 76 glog.Fatalf("Problem downloading Skia: %s", err) | 81 glog.Fatalf("Problem downloading Skia: %s", err) |
| 77 } | 82 } |
| 78 | 83 |
| 79 fuzzPipelines := make([]backend.FuzzPipeline, 0, len(*fuzzesToRun)) | 84 fuzzPipelines := make([]backend.FuzzPipeline, 0, len(*fuzzesToRun)) |
| 80 | 85 |
| 81 for _, category := range *fuzzesToRun { | 86 for _, category := range *fuzzesToRun { |
| 82 gen := generator.New(category) | 87 gen := generator.New(category) |
| 83 if err := gen.DownloadSeedFiles(storageClient); err != nil { | 88 if err := gen.DownloadSeedFiles(storageClient); err != nil { |
| 84 glog.Fatalf("Problem downloading binary seed files: %s", err) | 89 glog.Fatalf("Problem downloading binary seed files: %s", err) |
| 85 } | 90 } |
| 86 | 91 |
| 87 // If we are reanalyzing, no point in running the generator firs t, just to stop it. | 92 // If we are reanalyzing, no point in running the generator firs t, just to stop it. |
| 88 » » if !*skipGeneration && !*forceReanalysis { | 93 » » if !*forceReanalysis { |
|
borenet
2016/02/11 12:23:28
Not sure if you meant to remove skipGeneration her
kjlubick
2016/02/11 17:54:41
It'll be fine. The very next CL will add the othe
| |
| 89 glog.Infof("Starting %s generator with configuration %#v ", category, config.Generator) | 94 glog.Infof("Starting %s generator with configuration %#v ", category, config.Generator) |
| 90 if err := gen.Start(); err != nil { | 95 if err := gen.Start(); err != nil { |
| 91 glog.Fatalf("Problem starting binary generator: %s", err) | 96 glog.Fatalf("Problem starting binary generator: %s", err) |
| 92 } | 97 } |
| 93 } else { | 98 } else { |
| 94 glog.Infof("Skipping %s generator because --skip_generat ion is enabled", category) | 99 glog.Infof("Skipping %s generator because --skip_generat ion is enabled", category) |
| 95 } | 100 } |
| 96 | 101 |
| 97 glog.Infof("Starting %s aggregator with configuration %#v", cate gory, config.Aggregator) | 102 glog.Infof("Starting %s aggregator with configuration %#v", cate gory, config.Aggregator) |
| 98 agg, err := aggregator.StartAggregator(storageClient, category) | 103 agg, err := aggregator.StartAggregator(storageClient, category) |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 182 client, err := auth.NewDefaultJWTServiceAccountClient(auth.SCOPE_READ_WR ITE) | 187 client, err := auth.NewDefaultJWTServiceAccountClient(auth.SCOPE_READ_WR ITE) |
| 183 if err != nil { | 188 if err != nil { |
| 184 return fmt.Errorf("Problem setting up client OAuth: %v", err) | 189 return fmt.Errorf("Problem setting up client OAuth: %v", err) |
| 185 } | 190 } |
| 186 | 191 |
| 187 if storageClient, err = storage.NewClient(context.Background(), cloud.Wi thBaseHTTP(client)); err != nil { | 192 if storageClient, err = storage.NewClient(context.Background(), cloud.Wi thBaseHTTP(client)); err != nil { |
| 188 return fmt.Errorf("Problem authenticating: %v", err) | 193 return fmt.Errorf("Problem authenticating: %v", err) |
| 189 } | 194 } |
| 190 return nil | 195 return nil |
| 191 } | 196 } |
| OLD | NEW |