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