| OLD | NEW |
| 1 # Copyright 2016 The Chromium Authors. All rights reserved. | 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 | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 import logging | 5 import logging |
| 6 | 6 |
| 7 from crash import classifier | 7 from crash.occurrence import RankByOccurrence |
| 8 from crash.type_enums import CallStackLanguageType | 8 from crash.type_enums import CallStackLanguageType |
| 9 from model.crash.crash_config import CrashConfig | 9 from model.crash.crash_config import CrashConfig |
| 10 | 10 |
| 11 | 11 class ProjectClassifier(object): |
| 12 class ProjectClassifier(classifier.Classifier): | |
| 13 """Determines the project of a crash - (project_name, project_path). | 12 """Determines the project of a crash - (project_name, project_path). |
| 14 | 13 |
| 15 For example: ('chromium', 'src/'), ('skia', 'src/skia/'), ...etc. | 14 For example: ('chromium', 'src/'), ('skia', 'src/skia/'), ...etc. |
| 16 """ | 15 """ |
| 17 | 16 |
| 18 def __init__(self): | 17 def __init__(self): |
| 19 super(ProjectClassifier, self).__init__() | 18 super(ProjectClassifier, self).__init__() |
| 20 self.project_classifier_config = CrashConfig.Get().project_classifier | 19 self.project_classifier_config = CrashConfig.Get().project_classifier |
| 21 if self.project_classifier_config: | 20 if self.project_classifier_config: |
| 22 self.project_classifier_config['host_directories'].sort( | 21 self.project_classifier_config['host_directories'].sort( |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 55 def GetClassFromResult(self, result): | 54 def GetClassFromResult(self, result): |
| 56 """Returns (project_name, project_path) of a Result.""" | 55 """Returns (project_name, project_path) of a Result.""" |
| 57 if result.file_to_stack_infos: | 56 if result.file_to_stack_infos: |
| 58 # A file in culprit result should always have its stack_info, namely a | 57 # A file in culprit result should always have its stack_info, namely a |
| 59 # list of (frame, callstack_priority) pairs. | 58 # list of (frame, callstack_priority) pairs. |
| 60 frame, _ = result.file_to_stack_infos.values()[0][0] | 59 frame, _ = result.file_to_stack_infos.values()[0][0] |
| 61 return self.GetClassFromStackFrame(frame) | 60 return self.GetClassFromStackFrame(frame) |
| 62 | 61 |
| 63 return '' | 62 return '' |
| 64 | 63 |
| 64 # TODO(wrengr): should return an object of some "Project" class; |
| 65 # similar to how we handle components. |
| 65 def Classify(self, results, crash_stack): | 66 def Classify(self, results, crash_stack): |
| 66 """Classify project of a crash. | 67 """Classify project of a crash. |
| 67 | 68 |
| 68 Args: | 69 Args: |
| 69 results (list of Result): culprit results. | 70 results (list of Result): culprit results. |
| 70 crash_stack (CallStack): the callstack that caused the crash. | 71 crash_stack (CallStack): the callstack that caused the crash. |
| 71 | 72 |
| 72 Returns: | 73 Returns: |
| 73 A tuple, project of the crash - (project_name, project_path). | 74 A tuple, project of the crash - (project_name, project_path). |
| 74 """ | 75 """ |
| 75 if not self.project_classifier_config: | 76 if not self.project_classifier_config: |
| 76 logging.warning('Empty configuration for project classifier.') | 77 logging.warning('ProjectClassifier.Classify: Empty configuration.') |
| 77 return '' | 78 return None |
| 78 | 79 |
| 79 def _GetRankFunction(language_type): | 80 rank_function = None |
| 80 if language_type == CallStackLanguageType.JAVA: | 81 if crash_stack.language_type == CallStackLanguageType.JAVA: |
| 81 def _RankFunctionForJava(occurrence): | 82 def _RankFunctionForJava(occurrence): |
| 82 project_name = occurrence.name | 83 project_name = occurrence.name |
| 83 return (len(occurrence), | 84 return (len(occurrence), |
| 84 0 if 'chromium' in project_name else | 85 0 if 'chromium' in project_name else |
| 85 self.project_classifier_config[ | 86 self.project_classifier_config[ |
| 86 'non_chromium_project_rank_priority'][project_name]) | 87 'non_chromium_project_rank_priority'][project_name]) |
| 87 | 88 |
| 88 return _RankFunctionForJava | 89 rank_function = _RankFunctionForJava |
| 89 | 90 |
| 90 return classifier.DefaultRankFunction | 91 top_n_frames = self.project_classifier_config['top_n'] |
| 92 # If |results| are available, we use the projects from there since |
| 93 # they're more reliable than the ones from the |crash_stack|. |
| 94 if results: |
| 95 classes = map(self.GetClassFromResult, results[:top_n_frames]) |
| 96 else: |
| 97 classes = map(self.GetClassFromStackFrame, crash_stack[:top_n_frames]) |
| 91 | 98 |
| 92 # Set the max_classes to 1, so the returned projects only has one element. | 99 # Since we're only going to return the highest-ranked class, might |
| 93 projects = self._Classify( | 100 # as well set |max_classes| to 1. |
| 94 results, crash_stack, | 101 projects = RankByOccurrence(classes, 1, rank_function=rank_function) |
| 95 self.project_classifier_config['top_n'], 1, | |
| 96 rank_function=_GetRankFunction(crash_stack.language_type)) | |
| 97 | 102 |
| 98 if projects: | 103 if projects: |
| 104 if projects[0] is None: |
| 105 logging.warning('ProjectClassifier.Classify: the highest ranking project
is None.') |
| 99 return projects[0] | 106 return projects[0] |
| 100 | 107 |
| 101 return '' | 108 logging.warning('ProjectClassifier.Classify: no projects found.') |
| 109 return None |
| OLD | NEW |