How to use _process_info_line method in autotest

Best Python code snippet using autotest_python

stack_core.py

Source:stack_core.py Github

copy

Full Screen

1#!/usr/bin/env python2#3# Copyright (C) 2013 The Android Open Source Project4#5# Licensed under the Apache License, Version 2.0 (the "License");6# you may not use this file except in compliance with the License.7# You may obtain a copy of the License at8#9# http://www.apache.org/licenses/LICENSE-2.010#11# Unless required by applicable law or agreed to in writing, software12# distributed under the License is distributed on an "AS IS" BASIS,13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.14# See the License for the specific language governing permissions and15# limitations under the License.16"""stack symbolizes native crash dumps."""17import itertools18import logging19import multiprocessing20import os21import re22import subprocess23import time24import symbol25UNKNOWN = '<unknown>'26HEAP = '[heap]'27STACK = '[stack]'28_DEFAULT_JOBS=829_CHUNK_SIZE = 100030_BASE_APK = 'base.apk'31_LIBCHROME_SO = 'libchrome.so'32_PROCESS_INFO_LINE = re.compile('(pid: [0-9]+, tid: [0-9]+.*)')33_SIGNAL_LINE = re.compile('(signal [0-9]+ \(.*\).*)')34_REGISTER_LINE = re.compile('(([ ]*[0-9a-z]{2} [0-9a-f]{8}){4})')35_THREAD_LINE = re.compile('(.*)(\-\-\- ){15}\-\-\-')36_DALVIK_JNI_THREAD_LINE = re.compile("(\".*\" prio=[0-9]+ tid=[0-9]+ NATIVE.*)")37_DALVIK_NATIVE_THREAD_LINE = re.compile("(\".*\" sysTid=[0-9]+ nice=[0-9]+.*)")38_WIDTH = '{8}'39if symbol.ARCH == 'arm64' or symbol.ARCH == 'x86_64' or symbol.ARCH == 'x64':40 _WIDTH = '{16}'41# Matches LOG(FATAL) lines, like the following example:42# [FATAL:source_file.cc(33)] Check failed: !instances_.empty()43_LOG_FATAL_LINE = re.compile('(\[FATAL\:.*\].*)$')44# Note that both trace and value line matching allow for variable amounts of45# whitespace (e.g. \t). This is because the we want to allow for the stack46# tool to operate on AndroidFeedback provided system logs. AndroidFeedback47# strips out double spaces that are found in tombsone files and logcat output.48#49# Examples of matched trace lines include lines from tombstone files like:50# #00 pc 001cf42e /data/data/com.my.project/lib/libmyproject.so51# #00 pc 001cf42e /data/data/com.my.project/lib/libmyproject.so (symbol)52# Or lines from AndroidFeedback crash report system logs like:53# 03-25 00:51:05.520 I/DEBUG ( 65): #00 pc 001cf42e /data/data/com.my.project/lib/libmyproject.so54# Please note the spacing differences.55_TRACE_LINE = re.compile('(.*)\#(?P<frame>[0-9]+)[ \t]+(..)[ \t]+(0x)?(?P<address>[0-9a-f]{0,16})[ \t]+(?P<lib>[^\r\n \t]*)(?P<symbol_present> \((?P<symbol_name>.*)\))?') # pylint: disable-msg=C631056# Matches lines emitted by src/base/debug/stack_trace_android.cc, like:57# #00 0x7324d92d /data/app-lib/org.chromium.native_test-1/libbase.cr.so+0x0006992d58# This pattern includes the unused named capture groups <symbol_present> and59# <symbol_name> so that it can interoperate with the |_TRACE_LINE| regex.60_DEBUG_TRACE_LINE = re.compile(61 '(.*)(?P<frame>\#[0-9]+ 0x[0-9a-f]' + _WIDTH + ') '62 '(?P<lib>[^+]+)\+0x(?P<address>[0-9a-f]' + _WIDTH + ')'63 '(?P<symbol_present>)(?P<symbol_name>)')64# Examples of matched value lines include:65# bea4170c 8018e4e9 /data/data/com.my.project/lib/libmyproject.so66# bea4170c 8018e4e9 /data/data/com.my.project/lib/libmyproject.so (symbol)67# 03-25 00:51:05.530 I/DEBUG ( 65): bea4170c 8018e4e9 /data/data/com.my.project/lib/libmyproject.so68# Again, note the spacing differences.69_VALUE_LINE = re.compile('(.*)([0-9a-f]' + _WIDTH + ')[ \t]+([0-9a-f]' + _WIDTH + ')[ \t]+([^\r\n \t]*)( \((.*)\))?')70# Lines from 'code around' sections of the output will be matched before71# value lines because otheriwse the 'code around' sections will be confused as72# value lines.73#74# Examples include:75# 801cf40c ffffc4cc 00b2f2c5 00b2f1c7 00c1e1a876# 03-25 00:51:05.530 I/DEBUG ( 65): 801cf40c ffffc4cc 00b2f2c5 00b2f1c7 00c1e1a877code_line = re.compile('(.*)[ \t]*[a-f0-9]' + _WIDTH + '[ \t]*[a-f0-9]' + _WIDTH +78 '[ \t]*[a-f0-9]' + _WIDTH + '[ \t]*[a-f0-9]' + _WIDTH +79 '[ \t]*[a-f0-9]' + _WIDTH + '[ \t]*[ \r\n]') # pylint: disable-msg=C631080def PrintTraceLines(trace_lines):81 """Print back trace."""82 maxlen = max(map(lambda tl: len(tl[1]), trace_lines))83 print84 print 'Stack Trace:'85 print ' RELADDR ' + 'FUNCTION'.ljust(maxlen) + ' FILE:LINE'86 for tl in trace_lines:87 (addr, symbol_with_offset, location) = tl88 normalized = os.path.normpath(location)89 print ' %8s %s %s' % (addr, symbol_with_offset.ljust(maxlen), normalized)90 return91def PrintValueLines(value_lines):92 """Print stack data values."""93 maxlen = max(map(lambda tl: len(tl[2]), value_lines))94 print95 print 'Stack Data:'96 print ' ADDR VALUE ' + 'FUNCTION'.ljust(maxlen) + ' FILE:LINE'97 for vl in value_lines:98 (addr, value, symbol_with_offset, location) = vl99 print ' %8s %8s %s %s' % (addr, value, symbol_with_offset.ljust(maxlen), location)100 return101def PrintOutput(trace_lines, value_lines, more_info):102 if trace_lines:103 PrintTraceLines(trace_lines)104 if value_lines:105 # TODO(cjhopman): it seems that symbol.SymbolInformation always fails to106 # find information for addresses in value_lines in chrome libraries, and so107 # value_lines have little value to us and merely clutter the output.108 # Since information is sometimes contained in these lines (from system109 # libraries), don't completely disable them.110 if more_info:111 PrintValueLines(value_lines)112def PrintDivider():113 print114 print '-----------------------------------------------------\n'115def ConvertTrace(lines, load_vaddrs, more_info):116 """Convert strings containing native crash to a stack."""117 start = time.time()118 chunks = [lines[i: i+_CHUNK_SIZE] for i in xrange(0, len(lines), _CHUNK_SIZE)]119 pool = multiprocessing.Pool(processes=_DEFAULT_JOBS)120 useful_log = itertools.chain(*pool.map(PreProcessLog(load_vaddrs), chunks))121 pool.close()122 pool.join()123 end = time.time()124 logging.debug('Finished processing. Elapsed time: %.4fs', (end - start))125 ResolveCrashSymbol(list(useful_log), more_info)126 end = time.time()127 logging.debug('Finished resolving symbols. Elapsed time: %.4fs',128 (end - start))129class PreProcessLog:130 """Closure wrapper, for multiprocessing.Pool.map."""131 def __init__(self, load_vaddrs):132 """Bind load_vaddrs to the PreProcessLog closure.133 Args:134 load_vaddrs: LOAD segment min_vaddrs keyed on mapped executable135 """136 self._load_vaddrs = load_vaddrs;137 def _AdjustAddress(self, address, lib):138 """Add the vaddr of the library's first LOAD segment to address.139 Args:140 address: symbol address as a hexadecimal string141 lib: path to loaded library142 Returns:143 address+load_vaddrs[key] if lib ends with /key, otherwise address144 """145 for key, offset in self._load_vaddrs.iteritems():146 if lib.endswith('/' + key):147 # Add offset to address, and return the result as a hexadecimal string148 # with the same number of digits as the original. This allows the149 # caller to make a direct textual substitution.150 return ('%%0%dx' % len(address)) % (int(address, 16) + offset)151 return address152 def __call__(self, lines):153 """Preprocess the strings, only keep the useful ones.154 Args:155 lines: a list of byte strings read from logcat156 Returns:157 A list of unicode strings related to native crash158 """159 useful_log = []160 for ln in lines:161 line = unicode(ln, errors='ignore')162 if (_PROCESS_INFO_LINE.search(line)163 or _SIGNAL_LINE.search(line)164 or _REGISTER_LINE.search(line)165 or _THREAD_LINE.search(line)166 or _DALVIK_JNI_THREAD_LINE.search(line)167 or _DALVIK_NATIVE_THREAD_LINE.search(line)168 or _LOG_FATAL_LINE.search(line)169 or _DEBUG_TRACE_LINE.match(line)):170 useful_log.append(line)171 continue172 match = _TRACE_LINE.match(line)173 if match:174 # If the trace line suggests a direct load from APK, replace the175 # APK name with libchrome.so. Current load from APK supports only176 # single library load, so it must be libchrome.so that was loaded177 # in this way.178 line = line.replace('/' + _BASE_APK, '/' + _LIBCHROME_SO)179 # For trace lines specifically, the address may need to be adjusted180 # to account for relocation packing. This is because debuggerd on181 # pre-M platforms does not understand non-zero vaddr LOAD segments.182 address, lib = match.group('address', 'lib')183 adjusted_address = self._AdjustAddress(address, lib)184 useful_log.append(line.replace(address, adjusted_address, 1))185 continue186 if code_line.match(line):187 # Code lines should be ignored. If this were excluded the 'code around'188 # sections would trigger value_line matches.189 continue190 if _VALUE_LINE.match(line):191 useful_log.append(line)192 return useful_log193def ResolveCrashSymbol(lines, more_info):194 """Convert unicode strings which contains native crash to a stack195 """196 trace_lines = []197 value_lines = []198 last_frame = -1199 # It is faster to get symbol information with a single call rather than with200 # separate calls for each line. Since symbol.SymbolInformation caches results,201 # we can extract all the addresses that we will want symbol information for202 # from the log and call symbol.SymbolInformation so that the results are203 # cached in the following lookups.204 code_addresses = {}205 for line in lines:206 lib, address = None, None207 match = _TRACE_LINE.match(line) or _DEBUG_TRACE_LINE.match(line)208 if match:209 address, lib = match.group('address', 'lib')210 match = _VALUE_LINE.match(line)211 if match and not code_line.match(line):212 (_0, _1, address, lib, _2, _3) = match.groups()213 if lib:214 code_addresses.setdefault(lib, set()).add(address)215 for lib in code_addresses:216 symbol.SymbolInformationForSet(217 symbol.TranslateLibPath(lib), code_addresses[lib], more_info)218 for line in lines:219 # AndroidFeedback adds zero width spaces into its crash reports. These220 # should be removed or the regular expresssions will fail to match.221 process_header = _PROCESS_INFO_LINE.search(line)222 signal_header = _SIGNAL_LINE.search(line)223 register_header = _REGISTER_LINE.search(line)224 thread_header = _THREAD_LINE.search(line)225 dalvik_jni_thread_header = _DALVIK_JNI_THREAD_LINE.search(line)226 dalvik_native_thread_header = _DALVIK_NATIVE_THREAD_LINE.search(line)227 log_fatal_header = _LOG_FATAL_LINE.search(line)228 if (process_header or signal_header or register_header or thread_header or229 dalvik_jni_thread_header or dalvik_native_thread_header or230 log_fatal_header) :231 if trace_lines or value_lines:232 PrintOutput(trace_lines, value_lines, more_info)233 PrintDivider()234 trace_lines = []235 value_lines = []236 last_frame = -1237 if process_header:238 print process_header.group(1)239 if signal_header:240 print signal_header.group(1)241 if register_header:242 print register_header.group(1)243 if thread_header:244 print thread_header.group(1)245 if dalvik_jni_thread_header:246 print dalvik_jni_thread_header.group(1)247 if dalvik_native_thread_header:248 print dalvik_native_thread_header.group(1)249 if log_fatal_header:250 print log_fatal_header.group(1)251 continue252 match = _TRACE_LINE.match(line) or _DEBUG_TRACE_LINE.match(line)253 if match:254 frame, code_addr, area, symbol_present, symbol_name = match.group(255 'frame', 'address', 'lib', 'symbol_present', 'symbol_name')256 logging.debug('Found trace line: %s' % line.strip())257 if frame <= last_frame and (trace_lines or value_lines):258 PrintOutput(trace_lines, value_lines, more_info)259 PrintDivider()260 trace_lines = []261 value_lines = []262 last_frame = frame263 if area == UNKNOWN or area == HEAP or area == STACK:264 trace_lines.append((code_addr, '', area))265 else:266 logging.debug('Identified lib: %s' % area)267 # If a calls b which further calls c and c is inlined to b, we want to268 # display "a -> b -> c" in the stack trace instead of just "a -> c"269 info = symbol.SymbolInformation(area, code_addr, more_info)270 logging.debug('symbol information: %s' % info)271 nest_count = len(info) - 1272 for (source_symbol, source_location, object_symbol_with_offset) in info:273 if not source_symbol:274 if symbol_present:275 source_symbol = symbol.CallCppFilt(symbol_name)276 else:277 source_symbol = UNKNOWN278 if not source_location:279 source_location = area280 if nest_count > 0:281 nest_count = nest_count - 1282 trace_lines.append(('v------>', source_symbol, source_location))283 else:284 if not object_symbol_with_offset:285 object_symbol_with_offset = source_symbol286 trace_lines.append((code_addr,287 object_symbol_with_offset,288 source_location))289 match = _VALUE_LINE.match(line)290 if match:291 (unused_, addr, value, area, symbol_present, symbol_name) = match.groups()292 if area == UNKNOWN or area == HEAP or area == STACK or not area:293 value_lines.append((addr, value, '', area))294 else:295 info = symbol.SymbolInformation(area, value, more_info)296 (source_symbol, source_location, object_symbol_with_offset) = info.pop()297 if not source_symbol:298 if symbol_present:299 source_symbol = symbol.CallCppFilt(symbol_name)300 else:301 source_symbol = UNKNOWN302 if not source_location:303 source_location = area304 if not object_symbol_with_offset:305 object_symbol_with_offset = source_symbol306 value_lines.append((addr,307 value,308 object_symbol_with_offset,309 source_location))...

Full Screen

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run autotest automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful