| OLD | NEW |
| (Empty) | |
| 1 # Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. |
| 4 |
| 5 import argparse |
| 6 import json |
| 7 import logging |
| 8 import os |
| 9 import sys |
| 10 import threading |
| 11 import traceback |
| 12 |
| 13 _SCRIPT_DIR = os.path.join(os.path.dirname(__file__), os.path.pardir, |
| 14 os.path.pardir) |
| 15 sys.path.insert(1, _SCRIPT_DIR) |
| 16 |
| 17 import script_util |
| 18 script_util.SetUpSystemPaths() |
| 19 |
| 20 from common.chrome_dependency_fetcher import ChromeDependencyFetcher |
| 21 from crash.crash_pipeline import FinditForClientID |
| 22 from crash.crash_report import CrashReport |
| 23 from crash.culprit import Culprit |
| 24 from crash.detect_regression_range import DetectRegressionRange |
| 25 from crash.findit_for_chromecrash import FinditForChromeCrash |
| 26 from crash.type_enums import CrashClient |
| 27 from crash_queries.delta_test import delta_util |
| 28 from git_checkout.local_git_repository import LocalGitRepository |
| 29 from model.crash.crash_config import CrashConfig |
| 30 import remote_api |
| 31 |
| 32 _FRACAS_FEEDBACK_URL_TEMPLATE = ( |
| 33 'https://%s.appspot.com/crash/fracas-result-feedback?key=%s') |
| 34 |
| 35 |
| 36 |
| 37 def StoreResults(crash, client_id, app_id, id_to_culprits, lock, verbose=False): |
| 38 """Stores findit result of crash into id_to_culprits dict.""" |
| 39 crash_url = _FRACAS_FEEDBACK_URL_TEMPLATE % (app_id, crash['id']) |
| 40 try: |
| 41 findit = FinditForClientID(client_id, LocalGitRepository()) |
| 42 stacktrace = findit._stacktrace_parser.Parse( |
| 43 crash['stack_trace'], |
| 44 ChromeDependencyFetcher(findit._repository).GetDependency( |
| 45 crash['crashed_version'], |
| 46 crash['platform'])) |
| 47 if stacktrace: |
| 48 culprit = findit._predator.FindCulprit(CrashReport( |
| 49 crashed_version=crash['crashed_version'], |
| 50 signature=crash['signature'], |
| 51 platform=crash['platform'], |
| 52 stacktrace=stacktrace, |
| 53 regression_range=crash['regression_range'])) |
| 54 else: |
| 55 culprit = None |
| 56 with lock: |
| 57 id_to_culprits[crash['id']] = culprit |
| 58 if verbose: |
| 59 print '\n\nCrash:', crash_url |
| 60 print json.dumps(culprit.ToDicts()[0] if culprit else {'found': False}, |
| 61 indent=4, sort_keys=True) |
| 62 except Exception: |
| 63 with lock: |
| 64 id_to_culprits[crash['id']] = None |
| 65 print '\n\nCrash:', crash_url |
| 66 print traceback.format_exc() |
| 67 |
| 68 |
| 69 def GetCulprits(crashes, client_id, app_id, verbose=False): |
| 70 """Run predator analysis on crashes locally.""" |
| 71 # Enable remote access to app engine services. |
| 72 remote_api.EnableRemoteApi(app_id) |
| 73 origin_get = CrashConfig.Get |
| 74 try: |
| 75 # This hack is to solve flaky BadStatusLine excepion(crbug.com/666150) in |
| 76 # remote api when key.get() gets called in threads. |
| 77 # TODO(katesonia): Remove this hack after crbug.com/659354 is done. |
| 78 CrashConfig.Get = script_util.GetLockedMethod(CrashConfig, 'Get', |
| 79 threading.Lock()) |
| 80 id_to_culprits = {} |
| 81 tasks = [] |
| 82 lock = threading.Lock() |
| 83 for crash in crashes: |
| 84 crash['regression_range'] = DetectRegressionRange( |
| 85 crash['historical_metadata']) |
| 86 tasks.append({ |
| 87 'function': StoreResults, |
| 88 'args': [crash, client_id, app_id, id_to_culprits, lock], |
| 89 'kwargs': {'verbose': verbose} |
| 90 }) |
| 91 script_util.RunTasks(tasks) |
| 92 |
| 93 return id_to_culprits |
| 94 finally: |
| 95 CrashConfig.Get = origin_get |
| 96 |
| 97 |
| 98 def RunPredator(): |
| 99 """Runs delta testing between 2 different Findit versions.""" |
| 100 argparser = argparse.ArgumentParser( |
| 101 description='Run Predator on a batch of crashes.') |
| 102 argparser.add_argument('result_path', help='Path to store results') |
| 103 argparser.add_argument('client', help=('Possible values are: fracas, cracas, ' |
| 104 'clusterfuzz. Right now, only fracas ' |
| 105 'is supported.')) |
| 106 argparser.add_argument('app', help='App engine id to get config from.') |
| 107 argparser.add_argument( |
| 108 '--verbose', |
| 109 '-v', |
| 110 action='store_true', |
| 111 default=False, |
| 112 help='Print findit results.') |
| 113 args = argparser.parse_args() |
| 114 |
| 115 crashes = json.loads(raw_input()) |
| 116 if not crashes: |
| 117 logging.error('Failed to get crashes info.') |
| 118 return |
| 119 |
| 120 culprits = GetCulprits(crashes, args.client, args.app, args.verbose) |
| 121 delta_util.FlushResult(culprits, args.result_path) |
| 122 |
| 123 |
| 124 if __name__ == '__main__': |
| 125 # Disable the trivial loggings inside predator. |
| 126 logging.basicConfig(level=logging.ERROR) |
| 127 RunPredator() |
| OLD | NEW |