Chromium Code Reviews| 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 from collections import namedtuple | |
| 5 import re | 6 import re |
| 6 | 7 |
| 7 from crash.type_enums import CallStackFormatType | 8 from crash.type_enums import CallStackFormatType |
| 8 from crash.type_enums import LanguageType | 9 from crash.type_enums import LanguageType |
| 9 from crash.type_enums import SanitizerType | 10 from crash.type_enums import SanitizerType |
| 10 | 11 |
| 11 | 12 |
| 13 class StartOfCallStack( | |
| 14 namedtuple('StartOfCallStack', | |
|
wrengr
2016/12/29 20:13:02
I'd put this on the previous line, to match the st
Sharu Jiang
2016/12/29 21:40:14
Actually that's a wrong indentation. Didn't notice
| |
| 15 ['priority', 'format_type', 'language_type', 'metadata'])): | |
| 16 """Represents the start of a new callstack. | |
| 17 | |
|
wrengr
2016/12/29 20:13:02
Shouldn't there be a header word here? like "Prope
Sharu Jiang
2016/12/29 21:40:14
Done.
| |
| 18 priority (int): Priority of the new callstack. | |
| 19 format_type (CallStackFormatType): The format of the new callstack. | |
| 20 language_type (LanguageType): The language of the new callstack. | |
| 21 metadata (dict): Dict of metadata for the new callstack, e.g. pid of the | |
| 22 stack. | |
| 23 """ | |
| 24 __slots__ = () | |
| 25 | |
|
wrengr
2016/12/29 20:13:02
Maybe add a __new__ constructor, so that the metat
Sharu Jiang
2016/12/29 21:40:14
Done.
| |
| 26 def __str__(self): # pragma: no cover | |
| 27 return ('StartOfCallStack(priority = %d, format_type = %d, ' | |
|
wrengr
2016/12/29 20:13:02
Use '%s' and self.__class__.__name__ instead of re
Sharu Jiang
2016/12/29 21:40:14
Done.
| |
| 28 'language_type = %d, metadata = %s)' % (self.priority, | |
| 29 self.format_type, | |
| 30 self.language_type, | |
| 31 self.metadata)) | |
| 32 | |
| 33 | |
| 12 class CallStackDetector(object): | 34 class CallStackDetector(object): |
| 13 """Class for detecting the start of a particular sort of CallStack.""" | 35 """Class for detecting the start of a particular sort of CallStack.""" |
| 14 | 36 |
| 15 # TODO(crbug.com/677321) Make the return to be a namedtuple. | 37 # TODO(crbug.com/677321) Make the return to be a namedtuple. |
|
wrengr
2016/12/29 20:13:02
the todo is redundant now
Sharu Jiang
2016/12/29 21:40:14
Oops, should have cleaned this.
| |
| 16 def IsStartOfNewCallStack(self, line, flags=None): | 38 def __call__(self, line, flags=None): |
|
wrengr
2016/12/29 20:13:02
+1 to using __call__ :)
| |
| 17 """Determines whether a line is the start of a new callstack or not. | 39 """Determines whether a line is the start of a new callstack or not. |
| 18 | 40 |
| 19 Args: | 41 Args: |
| 20 line (str): The line to be checked. | 42 line (str): The line to be checked. |
| 21 flags (FlagManager): manager for keeping track of parsing flags. | 43 flags (FlagManager): manager for keeping track of parsing flags. |
| 22 | 44 |
| 23 Returns: | 45 Returns: |
| 24 A tuple - | 46 A ``StartOfCallStack`` or None if no callstack found. |
| 25 (is_new_callstack, priority, format_type, language_type, metadata) | |
| 26 is_new_callstack (bool): Boolean indicating whether this is the start of | |
| 27 a new callstack. | |
| 28 priority (int): Priority of a callstack. | |
| 29 format_type (CallStackFormatType): The format of the new callstack, or | |
| 30 None if there is no new callstack. | |
| 31 language_type (LanguageType): The language of the new callstack, or None | |
| 32 if there is no new callstack. | |
| 33 metadata (dict): Dict of metadata for the new callstack, e.g. pid of | |
| 34 the stack. | |
| 35 """ | 47 """ |
| 36 raise NotImplementedError() | 48 raise NotImplementedError() |
| 37 | 49 |
| 38 | 50 |
| 39 class AndroidJobDetector(CallStackDetector): | 51 class AndroidJobDetector(CallStackDetector): |
| 40 """Detects the start of an android job callstack.""" | 52 """Detects the start of an android job callstack.""" |
| 41 JAVA_LANG_CALLSTACK_START_PATTERN = r'^java\.[A-Za-z0-9$._]+' | 53 JAVA_LANG_CALLSTACK_START_PATTERN = r'^java\.[A-Za-z0-9$._]+' |
| 42 JAVA_ORG_GHROMIUM_CALLSTACK_START_PATTERN = r'^org\.chromium\.[A-Za-z0-9$._]+' | 54 JAVA_ORG_GHROMIUM_CALLSTACK_START_PATTERN = r'^org\.chromium\.[A-Za-z0-9$._]+' |
| 43 JAVA_CAUSED_BY_CALLSTACK_START_PATTERN = r'^Caused by:' | 55 JAVA_CAUSED_BY_CALLSTACK_START_PATTERN = r'^Caused by:' |
| 44 JAVA_ANDROID_CALLSTACK_START_PATTERN = ( | 56 JAVA_ANDROID_CALLSTACK_START_PATTERN = ( |
| 45 r'^(com\.google\.)?android\.[A-Za-z0-9$._]+') | 57 r'^(com\.google\.)?android\.[A-Za-z0-9$._]+') |
| 46 | 58 |
| 47 JAVA_CALLSTACK_START_REGEX = re.compile( | 59 JAVA_CALLSTACK_START_REGEX = re.compile( |
| 48 '|'.join([JAVA_LANG_CALLSTACK_START_PATTERN, | 60 '|'.join([JAVA_LANG_CALLSTACK_START_PATTERN, |
| 49 JAVA_ORG_GHROMIUM_CALLSTACK_START_PATTERN, | 61 JAVA_ORG_GHROMIUM_CALLSTACK_START_PATTERN, |
| 50 JAVA_CAUSED_BY_CALLSTACK_START_PATTERN, | 62 JAVA_CAUSED_BY_CALLSTACK_START_PATTERN, |
| 51 JAVA_ANDROID_CALLSTACK_START_PATTERN])) | 63 JAVA_ANDROID_CALLSTACK_START_PATTERN])) |
| 52 | 64 |
| 53 def IsStartOfNewCallStack(self, line, flags=None): | 65 def __call__(self, line, flags=None): |
| 54 if AndroidJobDetector.JAVA_CALLSTACK_START_REGEX.match(line): | 66 if AndroidJobDetector.JAVA_CALLSTACK_START_REGEX.match(line): |
| 55 # Only assign the highest priority to fatal exception stack or segv | 67 # Only assign the highest priority to fatal exception stack or segv |
| 56 # stack. | 68 # stack. |
| 57 if flags and flags.Get('java_main_stack_flag'): | 69 if flags and flags.Get('java_main_stack_flag'): |
| 58 flags.TurnOff('java_main_stack_flag') | 70 flags.TurnOff('java_main_stack_flag') |
| 59 return True, 0, CallStackFormatType.JAVA, LanguageType.JAVA, {} | 71 return StartOfCallStack(0, CallStackFormatType.JAVA, |
| 72 LanguageType.JAVA, {}) | |
| 60 | 73 |
| 61 return True, 1, CallStackFormatType.JAVA, LanguageType.JAVA, {} | 74 return StartOfCallStack(1, CallStackFormatType.JAVA, |
| 75 LanguageType.JAVA, {}) | |
| 62 | 76 |
| 63 return False, None, None, None, None | 77 return None |
| 64 | 78 |
| 65 | 79 |
| 66 class SyzyasanDetector(CallStackDetector): | 80 class SyzyasanDetector(CallStackDetector): |
| 67 """Detects the start of a syzyasn callstack.""" | 81 """Detects the start of a syzyasn callstack.""" |
| 68 SYZYASAN_CRASH_CALLSTACK_START_REGEX = re.compile(r'^Crash stack:$') | 82 SYZYASAN_CRASH_CALLSTACK_START_REGEX = re.compile(r'^Crash stack:$') |
| 69 SYZYASAN_NON_CRASH_CALLSTACK_START_REGEX = re.compile(r'^(?!Crash).* stack:$') | 83 SYZYASAN_NON_CRASH_CALLSTACK_START_REGEX = re.compile(r'^(?!Crash).* stack:$') |
| 70 | 84 |
| 71 def IsStartOfNewCallStack(self, line, flags=None): | 85 def __call__(self, line, flags=None): |
| 72 # In syzyasan build, new stack starts with 'crash stack:', | 86 # In syzyasan build, new stack starts with 'crash stack:', |
| 73 # 'freed stack:', etc. | 87 # 'freed stack:', etc. |
| 74 if SyzyasanDetector.SYZYASAN_CRASH_CALLSTACK_START_REGEX.match(line): | 88 if SyzyasanDetector.SYZYASAN_CRASH_CALLSTACK_START_REGEX.match(line): |
| 75 return True, 0, CallStackFormatType.SYZYASAN, LanguageType.CPP, {} | 89 return StartOfCallStack(0, CallStackFormatType.SYZYASAN, |
| 90 LanguageType.CPP, {}) | |
| 76 # Other callstacks all get priority 1. | 91 # Other callstacks all get priority 1. |
| 77 if SyzyasanDetector.SYZYASAN_NON_CRASH_CALLSTACK_START_REGEX.match(line): | 92 if SyzyasanDetector.SYZYASAN_NON_CRASH_CALLSTACK_START_REGEX.match(line): |
| 78 return True, 1, CallStackFormatType.SYZYASAN, LanguageType.CPP, {} | 93 return StartOfCallStack(1, CallStackFormatType.SYZYASAN, |
| 94 LanguageType.CPP, {}) | |
| 79 | 95 |
| 80 return False, None, None, None, None | 96 return None |
| 81 | 97 |
| 82 | 98 |
| 83 class TsanDetector(CallStackDetector): | 99 class TsanDetector(CallStackDetector): |
| 84 """Detects the start of a thread sanitizer callstack.""" | 100 """Detects the start of a thread sanitizer callstack.""" |
| 85 TSAN_CRASH_CALLSTACK_START_PATTERN1 = r'^(Read|Write) of size \d+' | 101 TSAN_CRASH_CALLSTACK_START_PATTERN1 = r'^(Read|Write) of size \d+' |
| 86 TSAN_CRASH_CALLSTACK_START_PATTERN2 = r'^[A-Z]+: ThreadSanitizer' | 102 TSAN_CRASH_CALLSTACK_START_PATTERN2 = r'^[A-Z]+: ThreadSanitizer' |
| 87 TSAN_ALLOCATION_CALLSTACK_START_PATTERN = ( | 103 TSAN_ALLOCATION_CALLSTACK_START_PATTERN = ( |
| 88 r'^Previous (write|read) of size \d+') | 104 r'^Previous (write|read) of size \d+') |
| 89 TSAN_LOCATION_CALLSTACK_START_PATTERN = ( | 105 TSAN_LOCATION_CALLSTACK_START_PATTERN = ( |
| 90 r'^Location is heap block of size \d+') | 106 r'^Location is heap block of size \d+') |
| 91 | 107 |
| 92 TSAN_CRASH_CALLSTACK_START_REGEX = re.compile( | 108 TSAN_CRASH_CALLSTACK_START_REGEX = re.compile( |
| 93 '|'.join([TSAN_CRASH_CALLSTACK_START_PATTERN1, | 109 '|'.join([TSAN_CRASH_CALLSTACK_START_PATTERN1, |
| 94 TSAN_CRASH_CALLSTACK_START_PATTERN2])) | 110 TSAN_CRASH_CALLSTACK_START_PATTERN2])) |
| 95 | 111 |
| 96 TSAN_NON_CRASH_CALLSTACK_START_REGEX = re.compile( | 112 TSAN_NON_CRASH_CALLSTACK_START_REGEX = re.compile( |
| 97 '|'.join([TSAN_ALLOCATION_CALLSTACK_START_PATTERN, | 113 '|'.join([TSAN_ALLOCATION_CALLSTACK_START_PATTERN, |
| 98 TSAN_LOCATION_CALLSTACK_START_PATTERN])) | 114 TSAN_LOCATION_CALLSTACK_START_PATTERN])) |
| 99 | 115 |
| 100 def IsStartOfNewCallStack(self, line, flags=None): | 116 def __call__(self, line, flags=None): |
| 101 # Crash stack gets priority 0. | 117 # Crash stack gets priority 0. |
| 102 if TsanDetector.TSAN_CRASH_CALLSTACK_START_REGEX.match(line): | 118 if TsanDetector.TSAN_CRASH_CALLSTACK_START_REGEX.match(line): |
| 103 return True, 0, CallStackFormatType.DEFAULT, LanguageType.CPP, {} | 119 return StartOfCallStack(0, CallStackFormatType.DEFAULT, |
| 120 LanguageType.CPP, {}) | |
| 104 | 121 |
| 105 # All other stacks get priority 1. | 122 # All other stacks get priority 1. |
| 106 if TsanDetector.TSAN_NON_CRASH_CALLSTACK_START_REGEX.match(line): | 123 if TsanDetector.TSAN_NON_CRASH_CALLSTACK_START_REGEX.match(line): |
| 107 return True, 1, CallStackFormatType.DEFAULT, LanguageType.CPP, {} | 124 return StartOfCallStack(1, CallStackFormatType.DEFAULT, |
| 125 LanguageType.CPP, {}) | |
| 108 | 126 |
| 109 return False, None, None, None, None | 127 return None |
| 110 | 128 |
| 111 | 129 |
| 112 class UbsanDetector(CallStackDetector): | 130 class UbsanDetector(CallStackDetector): |
| 113 """Detects the start of an undefined-behavior callstack.""" | 131 """Detects the start of an undefined-behavior callstack.""" |
| 114 UBSAN_CALLSTACK_START_REGEX = re.compile(r'^.*: runtime error: .*$') | 132 UBSAN_CALLSTACK_START_REGEX = re.compile(r'^.*: runtime error: .*$') |
| 115 | 133 |
| 116 def IsStartOfNewCallStack(self, line, flags=None): | 134 def __call__(self, line, flags=None): |
| 117 if UbsanDetector.UBSAN_CALLSTACK_START_REGEX.match(line): | 135 if UbsanDetector.UBSAN_CALLSTACK_START_REGEX.match(line): |
| 118 if flags and flags.Get('is_first_stack_flag'): | 136 if flags and flags.Get('is_first_stack_flag'): |
| 119 flags.TurnOff('is_first_stack_flag') | 137 flags.TurnOff('is_first_stack_flag') |
| 120 return True, 0, CallStackFormatType.DEFAULT, LanguageType.CPP, {} | 138 return StartOfCallStack(0, CallStackFormatType.DEFAULT, |
| 139 LanguageType.CPP, {}) | |
| 121 | 140 |
| 122 return True, 1, CallStackFormatType.DEFAULT, LanguageType.CPP, {} | 141 return StartOfCallStack(1, CallStackFormatType.DEFAULT, |
| 142 LanguageType.CPP, {}) | |
| 123 | 143 |
| 124 return False, None, None, None, None | 144 return None |
| 125 | 145 |
| 126 | 146 |
| 127 class MsanDetector(CallStackDetector): | 147 class MsanDetector(CallStackDetector): |
| 128 """Detects the start of a memory sanitizer callstack.""" | 148 """Detects the start of a memory sanitizer callstack.""" |
| 129 MSAN_CALLSTACK_START_REGEX = re.compile(r'^==(\d+)== ?([A-Z]+:|\w+Sanitizer)') | 149 MSAN_CALLSTACK_START_REGEX = re.compile(r'^==(\d+)== ?([A-Z]+:|\w+Sanitizer)') |
| 130 MSAN_CREATION_CALLSTACK_START_MARKER = 'Uninitialized value was created by' | 150 MSAN_CREATION_CALLSTACK_START_MARKER = 'Uninitialized value was created by' |
| 131 MSAN_STORAGE_CALLSTACK_START_MARKER = 'Uninitialized value was stored to' | 151 MSAN_STORAGE_CALLSTACK_START_MARKER = 'Uninitialized value was stored to' |
| 132 | 152 |
| 133 def IsStartOfNewCallStack(self, line, flags=None): | 153 def __call__(self, line, flags=None): |
| 134 # Assign the only msan stack priority 0. | 154 # Assign the only msan stack priority 0. |
| 135 if MsanDetector.MSAN_CREATION_CALLSTACK_START_MARKER in line: | 155 if MsanDetector.MSAN_CREATION_CALLSTACK_START_MARKER in line: |
| 136 return True, 0, CallStackFormatType.DEFAULT, LanguageType.CPP, {} | 156 return StartOfCallStack(0, CallStackFormatType.DEFAULT, |
| 157 LanguageType.CPP, {}) | |
| 137 if MsanDetector.MSAN_STORAGE_CALLSTACK_START_MARKER in line: | 158 if MsanDetector.MSAN_STORAGE_CALLSTACK_START_MARKER in line: |
| 138 return True, 1, CallStackFormatType.DEFAULT, LanguageType.CPP, {} | 159 return StartOfCallStack(1, CallStackFormatType.DEFAULT, |
| 160 LanguageType.CPP, {}) | |
| 139 msan_callstack_start_regex = ( | 161 msan_callstack_start_regex = ( |
| 140 MsanDetector.MSAN_CALLSTACK_START_REGEX.match(line)) | 162 MsanDetector.MSAN_CALLSTACK_START_REGEX.match(line)) |
| 141 if msan_callstack_start_regex: | 163 if msan_callstack_start_regex: |
| 142 return (True, 2, CallStackFormatType.DEFAULT, LanguageType.CPP, | 164 return StartOfCallStack( |
| 143 {'pid': int(msan_callstack_start_regex.group(1).strip())}) | 165 2, CallStackFormatType.DEFAULT, LanguageType.CPP, |
| 166 {'pid': int(msan_callstack_start_regex.group(1).strip())}) | |
| 144 | 167 |
| 145 return False, None, None, None, None | 168 return None |
| 146 | 169 |
| 147 | 170 |
| 148 class AsanDetector(CallStackDetector): | 171 class AsanDetector(CallStackDetector): |
| 149 """Detects the start of an address sanitizer callstack.""" | 172 """Detects the start of an address sanitizer callstack.""" |
| 150 ASAN_CRASH_CALLSTACK_START_REGEX1 = re.compile( | 173 ASAN_CRASH_CALLSTACK_START_REGEX1 = re.compile( |
| 151 r'^==(\d+)== ?([A-Z]+:|\w+Sanitizer)') | 174 r'^==(\d+)== ?([A-Z]+:|\w+Sanitizer)') |
| 152 ASAN_CRASH_CALLSTACK_START_REGEX2 = re.compile( | 175 ASAN_CRASH_CALLSTACK_START_REGEX2 = re.compile( |
| 153 r'^(READ|WRITE) of size \d+ at|^backtrace:') | 176 r'^(READ|WRITE) of size \d+ at|^backtrace:') |
| 154 | 177 |
| 155 ASAN_FREED_CALLSTACK_START_PATTERN = ( | 178 ASAN_FREED_CALLSTACK_START_PATTERN = ( |
| 156 r'^freed by thread T\d+ (.* )?here:') | 179 r'^freed by thread T\d+ (.* )?here:') |
| 157 ASAN_ALLOCATION_CALLSTACK_START_PATTERN = ( | 180 ASAN_ALLOCATION_CALLSTACK_START_PATTERN = ( |
| 158 r'^(previously )?allocated by thread T\d+ (.* )?here:') | 181 r'^(previously )?allocated by thread T\d+ (.* )?here:') |
| 159 ASAN_OTHER_CALLSTACK_START_PATTERN = ( | 182 ASAN_OTHER_CALLSTACK_START_PATTERN = ( |
| 160 r'^Thread T\d+ (.* )?created by') | 183 r'^Thread T\d+ (.* )?created by') |
| 161 | 184 |
| 162 ASAN_NON_CRASH_CALLSTACK_START_PATTERN = re.compile( | 185 ASAN_NON_CRASH_CALLSTACK_START_PATTERN = re.compile( |
| 163 '|'.join([ASAN_FREED_CALLSTACK_START_PATTERN, | 186 '|'.join([ASAN_FREED_CALLSTACK_START_PATTERN, |
| 164 ASAN_ALLOCATION_CALLSTACK_START_PATTERN, | 187 ASAN_ALLOCATION_CALLSTACK_START_PATTERN, |
| 165 ASAN_OTHER_CALLSTACK_START_PATTERN])) | 188 ASAN_OTHER_CALLSTACK_START_PATTERN])) |
| 166 | 189 |
| 167 def IsStartOfNewCallStack(self, line, flags=None): | 190 def __call__(self, line, flags=None): |
| 168 asan_crash_callstack_start_regex1_match = ( | 191 asan_crash_callstack_start_regex1_match = ( |
| 169 AsanDetector.ASAN_CRASH_CALLSTACK_START_REGEX1.match(line)) | 192 AsanDetector.ASAN_CRASH_CALLSTACK_START_REGEX1.match(line)) |
| 170 if asan_crash_callstack_start_regex1_match: | 193 if asan_crash_callstack_start_regex1_match: |
| 171 return (True, 0, CallStackFormatType.DEFAULT, LanguageType.CPP, | 194 return StartOfCallStack( |
| 172 {'pid': int( | 195 0, CallStackFormatType.DEFAULT, LanguageType.CPP, |
| 173 asan_crash_callstack_start_regex1_match.group(1).strip())}) | 196 {'pid': int( |
| 197 asan_crash_callstack_start_regex1_match.group(1).strip())}) | |
| 174 | 198 |
| 175 # Crash stack gets priority 0. | 199 # Crash stack gets priority 0. |
| 176 if AsanDetector.ASAN_CRASH_CALLSTACK_START_REGEX2.match(line): | 200 if AsanDetector.ASAN_CRASH_CALLSTACK_START_REGEX2.match(line): |
| 177 return True, 0, CallStackFormatType.DEFAULT, LanguageType.CPP, {} | 201 return StartOfCallStack(0, CallStackFormatType.DEFAULT, |
| 202 LanguageType.CPP, {}) | |
| 178 | 203 |
| 179 # All other callstack gets priority 1. | 204 # All other callstack gets priority 1. |
| 180 if AsanDetector.ASAN_NON_CRASH_CALLSTACK_START_PATTERN.match(line): | 205 if AsanDetector.ASAN_NON_CRASH_CALLSTACK_START_PATTERN.match(line): |
| 181 return True, 1, CallStackFormatType.DEFAULT, LanguageType.CPP, {} | 206 return StartOfCallStack(1, CallStackFormatType.DEFAULT, |
| 207 LanguageType.CPP, {}) | |
| 182 | 208 |
| 183 return False, None, None, None, None | 209 return None |
| 184 | 210 |
| 185 | 211 |
| 186 class ChromeCrashStackDetector(CallStackDetector): | 212 class ChromeCrashStackDetector(CallStackDetector): |
| 187 """Detects the start of an chromecrash(Fracas/Cracas) callstack.""" | 213 """Detects the start of an chromecrash(Fracas/Cracas) callstack.""" |
| 188 CHROME_CRASH_CALLSTACK_START_REGEX = re.compile(r'CRASHED \[(.*) @ 0x(.*)\]') | 214 CHROME_CRASH_CALLSTACK_START_REGEX = re.compile(r'CRASHED \[(.*) @ 0x(.*)\]') |
| 189 JAVA_CALLSTACK_START_REGEX = re.compile(r'\(JAVA\) CRASHED \[(.*) @ 0x(.*)\]') | 215 JAVA_CALLSTACK_START_REGEX = re.compile(r'\(JAVA\) CRASHED \[(.*) @ 0x(.*)\]') |
| 190 | 216 |
| 191 def IsStartOfNewCallStack(self, line, flags=None): | 217 def __call__(self, line, flags=None): |
| 192 if ChromeCrashStackDetector.CHROME_CRASH_CALLSTACK_START_REGEX.match(line): | 218 if ChromeCrashStackDetector.CHROME_CRASH_CALLSTACK_START_REGEX.match(line): |
| 193 # Fracas only provide magic signature stack (crash stack). | 219 # Fracas only provide magic signature stack (crash stack). |
| 194 return True, 0, CallStackFormatType.DEFAULT, LanguageType.CPP, {} | 220 return StartOfCallStack(0, CallStackFormatType.DEFAULT, |
| 221 LanguageType.CPP, {}) | |
| 195 | 222 |
| 196 if ChromeCrashStackDetector.JAVA_CALLSTACK_START_REGEX.match(line): | 223 if ChromeCrashStackDetector.JAVA_CALLSTACK_START_REGEX.match(line): |
| 197 return True, 0, CallStackFormatType.DEFAULT, LanguageType.JAVA, {} | 224 return StartOfCallStack(0, CallStackFormatType.DEFAULT, |
| 225 LanguageType.JAVA, {}) | |
| 198 | 226 |
| 199 return False, None, None, None, None | 227 return None |
| OLD | NEW |