| 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 copy |
| 6 |
| 7 from crash import classifier |
| 8 from crash.type_enums import CallStackLanguageType |
| 9 from model.crash.crash_config import CrashConfig |
| 10 |
| 11 |
| 12 class ProjectClassifier(classifier.Classifier): |
| 13 """Determines the project of a crash - (project_name, project_path). |
| 14 |
| 15 For example: ('chromium', 'src/'), ('skia', 'src/skia/'), ...etc. |
| 16 """ |
| 17 |
| 18 def __init__(self): |
| 19 super(ProjectClassifier, self).__init__() |
| 20 |
| 21 def _GetCompiledConfig(config): |
| 22 config = copy.copy(config) |
| 23 config['top_n'] = int(config['top_n']) |
| 24 return config |
| 25 |
| 26 self.config = _GetCompiledConfig(CrashConfig.Get().project_classifier) |
| 27 |
| 28 def _GetProjectNameFromDepPath(self, dep_path): |
| 29 """Returns the component name of a path.""" |
| 30 if dep_path == 'src/': |
| 31 return 'chromium' |
| 32 |
| 33 for host_directory in self.config['host_directories']: |
| 34 if dep_path.startswith(host_directory): |
| 35 path = dep_path[len(host_directory):] |
| 36 return 'chromium-%s' % path.split('/')[0].lower() |
| 37 |
| 38 # Unknown path, return the whole path as component name. |
| 39 return 'chromium-%s' % '_'.join(dep_path.split('/')) |
| 40 |
| 41 def GetClassFromStackFrame(self, frame): |
| 42 """Returns a tuple (project_name, project_path) of a StackFrame.""" |
| 43 if frame.dep_path: |
| 44 # Dep paths are parsed from chromium dependency, if a frame has non-empty |
| 45 # dep path, the project of this frame is chromium-*. |
| 46 return self._GetProjectNameFromDepPath(frame.dep_path), frame.dep_path |
| 47 |
| 48 for marker, name in self.config[ |
| 49 'function_marker_to_project_name'].iteritems(): |
| 50 if frame.function.startswith(marker): |
| 51 return name, '' |
| 52 |
| 53 for marker, name in self.config[ |
| 54 'file_path_marker_to_project_name'].iteritems(): |
| 55 if marker in frame.file_path or marker in frame.raw_file_path: |
| 56 return name, '' |
| 57 |
| 58 return 'others', '' |
| 59 |
| 60 def GetClassFromResult(self, result): |
| 61 """Returns (project_name, project_path) of a Result.""" |
| 62 if result.dep_path: |
| 63 # Dep paths are parsed from chromium dependency, if a result has non-empty |
| 64 # dep path, the project of this culprit result is chromium-*. |
| 65 return self._GetProjectNameFromDepPath(result.dep_path), result.dep_path |
| 66 |
| 67 if result.file_to_stack_infos: |
| 68 # A file in culprit result should always have its stack_info, namely a |
| 69 # list of (frame, callstack_priority) pairs. |
| 70 frame, _ = result.file_to_stack_infos.values()[0][0] |
| 71 return self.GetClassFromStackFrame(frame) |
| 72 |
| 73 return 'others', '' |
| 74 |
| 75 def Classify(self, results, crash_stack): |
| 76 """Classify project of a crash. |
| 77 |
| 78 Args: |
| 79 results (list of Result): culprit results. |
| 80 crash_stack (CallStack): the callstack that caused the crash. |
| 81 |
| 82 Returns: |
| 83 A tuple, project of the crash - (project_name, project_path). |
| 84 """ |
| 85 def _GetRankFunction(language_type): |
| 86 if language_type == CallStackLanguageType.JAVA: |
| 87 def _RankFunctionForJava(class_occurrences_info): |
| 88 project_name, _ = class_occurrences_info.name |
| 89 return (len(class_occurrences_info.occurrences), |
| 90 0 if 'chromium' in project_name else self.config[ |
| 91 'non_chromium_project_rank_priority'][project_name]) |
| 92 |
| 93 return _RankFunctionForJava |
| 94 |
| 95 return classifier.DefaultRankFunction |
| 96 |
| 97 # Set the max_classes to 1, so the returned projects only has one element. |
| 98 projects = self._Classify( |
| 99 results, crash_stack, |
| 100 self.config['top_n'], 1, |
| 101 rank_function=_GetRankFunction(crash_stack.language_type)) |
| 102 |
| 103 def _Format(project_name, project_path): |
| 104 if project_path: |
| 105 return '%s (%s)' % (project_name, project_path) |
| 106 |
| 107 return project_name |
| 108 |
| 109 if projects: |
| 110 return _Format(*projects[0]) |
| 111 |
| 112 return 'others' |
| OLD | NEW |