10d163575Sopenharmony_ci#!/usr/bin/env python 20d163575Sopenharmony_ci# -*- coding: utf-8 -*- 30d163575Sopenharmony_ci 40d163575Sopenharmony_ci# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. 50d163575Sopenharmony_ci# Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. 60d163575Sopenharmony_ci# 70d163575Sopenharmony_ci# Redistribution and use in source and binary forms, with or without modification, 80d163575Sopenharmony_ci# are permitted provided that the following conditions are met: 90d163575Sopenharmony_ci# 100d163575Sopenharmony_ci# 1. Redistributions of source code must retain the above copyright notice, this list of 110d163575Sopenharmony_ci# conditions and the following disclaimer. 120d163575Sopenharmony_ci# 130d163575Sopenharmony_ci# 2. Redistributions in binary form must reproduce the above copyright notice, this list 140d163575Sopenharmony_ci# of conditions and the following disclaimer in the documentation and/or other materials 150d163575Sopenharmony_ci# provided with the distribution. 160d163575Sopenharmony_ci# 170d163575Sopenharmony_ci# 3. Neither the name of the copyright holder nor the names of its contributors may be used 180d163575Sopenharmony_ci# to endorse or promote products derived from this software without specific prior written 190d163575Sopenharmony_ci# permission. 200d163575Sopenharmony_ci# 210d163575Sopenharmony_ci# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 220d163575Sopenharmony_ci# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 230d163575Sopenharmony_ci# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 240d163575Sopenharmony_ci# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 250d163575Sopenharmony_ci# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 260d163575Sopenharmony_ci# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 270d163575Sopenharmony_ci# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 280d163575Sopenharmony_ci# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 290d163575Sopenharmony_ci# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 300d163575Sopenharmony_ci# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 310d163575Sopenharmony_ci# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 320d163575Sopenharmony_ci 330d163575Sopenharmony_ciimport sys 340d163575Sopenharmony_ciimport os 350d163575Sopenharmony_ciimport argparse 360d163575Sopenharmony_ciimport io 370d163575Sopenharmony_ciimport commands 380d163575Sopenharmony_ci 390d163575Sopenharmony_cidef find_string(excinfo_file, string): 400d163575Sopenharmony_ci res = '' 410d163575Sopenharmony_ci with open(excinfo_file, 'r+') as f: 420d163575Sopenharmony_ci for lines in f: 430d163575Sopenharmony_ci if string in lines: 440d163575Sopenharmony_ci res = lines 450d163575Sopenharmony_ci break 460d163575Sopenharmony_ci return res 470d163575Sopenharmony_ci 480d163575Sopenharmony_cidef is_kernel_exc(excinfo_file): 490d163575Sopenharmony_ci res = find_string(excinfo_file, 'excFrom: kernel') 500d163575Sopenharmony_ci print(res) 510d163575Sopenharmony_ci return res != '' 520d163575Sopenharmony_ci 530d163575Sopenharmony_cidef is_user_exc(excinfo_file): 540d163575Sopenharmony_ci res = find_string(excinfo_file, 'excFrom: User') 550d163575Sopenharmony_ci print(res) 560d163575Sopenharmony_ci return res != '' 570d163575Sopenharmony_ci 580d163575Sopenharmony_cidef parse_string_line(excinfo_file, string): 590d163575Sopenharmony_ci line = find_string(excinfo_file, string) 600d163575Sopenharmony_ci if line == '': 610d163575Sopenharmony_ci print("%s is not in %s\n" %(string, excinfo_file)) 620d163575Sopenharmony_ci return '' 630d163575Sopenharmony_ci line = line.replace('\n', '') 640d163575Sopenharmony_ci strlist = line.split(' ') 650d163575Sopenharmony_ci return strlist 660d163575Sopenharmony_ci 670d163575Sopenharmony_cidef parse_kernel_pc_klr(excinfo_file, ohos_image_file, string, addr2line_cmd, objdump_cmd): 680d163575Sopenharmony_ci #parse pc 690d163575Sopenharmony_ci with open(excinfo_file, 'r+') as f: 700d163575Sopenharmony_ci start = 0 710d163575Sopenharmony_ci for lines in f.readlines(): 720d163575Sopenharmony_ci if 'excFrom: kernel' in lines: 730d163575Sopenharmony_ci if start == 1: 740d163575Sopenharmony_ci break 750d163575Sopenharmony_ci start = 1 760d163575Sopenharmony_ci if start and string in lines: 770d163575Sopenharmony_ci lines = lines[lines.find(string):] 780d163575Sopenharmony_ci strlist = lines.split() 790d163575Sopenharmony_ci cmd = "%s%s | grep %s: -B 10 -A 5 -w" % (objdump_cmd, ohos_image_file, strlist[2][2:]) 800d163575Sopenharmony_ci ret = commands.getoutput(cmd) 810d163575Sopenharmony_ci print(ret) 820d163575Sopenharmony_ci cmd = "%s%s %s" % (addr2line_cmd, ohos_image_file, strlist[2]) 830d163575Sopenharmony_ci ret = commands.getoutput(cmd) 840d163575Sopenharmony_ci ret = ret.split('\n') 850d163575Sopenharmony_ci print("<%s>%s<%s>\n") % (string, ret[0], strlist[2]) 860d163575Sopenharmony_ci return 0 870d163575Sopenharmony_ci return -1 880d163575Sopenharmony_ci 890d163575Sopenharmony_cidef parse_kernel_lr(excinfo_file, ohos_image_file, addr2line_cmd): 900d163575Sopenharmony_ci with open(excinfo_file, 'r+') as f: 910d163575Sopenharmony_ci start = 0 920d163575Sopenharmony_ci index = 1 930d163575Sopenharmony_ci for lines in f.readlines(): 940d163575Sopenharmony_ci if 'excFrom: kernel' in lines: 950d163575Sopenharmony_ci if start == 1: 960d163575Sopenharmony_ci break 970d163575Sopenharmony_ci start = 1 980d163575Sopenharmony_ci if start and 'lr =' in lines: 990d163575Sopenharmony_ci lines = lines[lines.find('lr ='):] 1000d163575Sopenharmony_ci strlist = lines.split() 1010d163575Sopenharmony_ci cmd = "%s%s %s" % (addr2line_cmd, ohos_image_file, strlist[2]) 1020d163575Sopenharmony_ci ret = commands.getoutput(cmd) 1030d163575Sopenharmony_ci ret = ret.split('\n') 1040d163575Sopenharmony_ci print("<%.2d>%s<%s>" % (index, ret[0], strlist[2])) 1050d163575Sopenharmony_ci index = index + 1 1060d163575Sopenharmony_ci 1070d163575Sopenharmony_cidef parse_kernel_exc(excinfo_file, ohos_image_file, addr2line_cmd, objdump_cmd): 1080d163575Sopenharmony_ci #parse pc, klr 1090d163575Sopenharmony_ci ret1 = parse_kernel_pc_klr(excinfo_file, ohos_image_file, 'pc', addr2line_cmd, objdump_cmd) 1100d163575Sopenharmony_ci ret2 = parse_kernel_pc_klr(excinfo_file, ohos_image_file, 'klr', addr2line_cmd, objdump_cmd) 1110d163575Sopenharmony_ci #parse lr 1120d163575Sopenharmony_ci parse_kernel_lr(excinfo_file, ohos_image_file, addr2line_cmd) 1130d163575Sopenharmony_ci return ret1 and ret2 1140d163575Sopenharmony_ci 1150d163575Sopenharmony_cidef parse_user_pc_ulr(excinfo_file, rootfs_dir, string, addr2line_cmd, objdump_cmd): 1160d163575Sopenharmony_ci #parse pc 1170d163575Sopenharmony_ci with open(excinfo_file, 'r+') as f: 1180d163575Sopenharmony_ci start = 0 1190d163575Sopenharmony_ci for lines in f.readlines(): 1200d163575Sopenharmony_ci if 'excFrom: User' in lines: 1210d163575Sopenharmony_ci if start == 1: 1220d163575Sopenharmony_ci break 1230d163575Sopenharmony_ci start = 1 1240d163575Sopenharmony_ci if start and string in lines: 1250d163575Sopenharmony_ci lines = lines[lines.find(string):] 1260d163575Sopenharmony_ci strlist = lines.split() 1270d163575Sopenharmony_ci if len(strlist) < 7: 1280d163575Sopenharmony_ci print('%s is error'%string) 1290d163575Sopenharmony_ci return 0 1300d163575Sopenharmony_ci cmd = "%s%s%s | grep %s: -B 10 -A 5 -w" % (objdump_cmd, rootfs_dir, strlist[4], strlist[6][2:]) 1310d163575Sopenharmony_ci ret = commands.getoutput(cmd) 1320d163575Sopenharmony_ci print(ret) 1330d163575Sopenharmony_ci cmd = "%s%s%s %s" % (addr2line_cmd, rootfs_dir, strlist[4], strlist[6]) 1340d163575Sopenharmony_ci ret = commands.getoutput(cmd) 1350d163575Sopenharmony_ci ret = ret.split('\n') 1360d163575Sopenharmony_ci print("<%s>%s<%s><%s>\n" % (string, ret[0], strlist[6], strlist[4])) 1370d163575Sopenharmony_ci return 0 1380d163575Sopenharmony_ci return -1 1390d163575Sopenharmony_ci 1400d163575Sopenharmony_cidef parse_user_lr(excinfo_file, rootfs_dir, addr2line_cmd): 1410d163575Sopenharmony_ci with open(excinfo_file, 'r+') as f: 1420d163575Sopenharmony_ci start = 0 1430d163575Sopenharmony_ci index = 1 1440d163575Sopenharmony_ci for lines in f.readlines(): 1450d163575Sopenharmony_ci if 'excFrom: User' in lines: 1460d163575Sopenharmony_ci if start == 1: 1470d163575Sopenharmony_ci break 1480d163575Sopenharmony_ci start = 1 1490d163575Sopenharmony_ci if start and 'lr =' in lines: 1500d163575Sopenharmony_ci lines = lines[lines.find('lr ='):] 1510d163575Sopenharmony_ci strlist = lines.split() 1520d163575Sopenharmony_ci if len(strlist) < 11: 1530d163575Sopenharmony_ci print('%s is error' % strlist) 1540d163575Sopenharmony_ci return 1550d163575Sopenharmony_ci cmd = "%s%s%s %s" % (addr2line_cmd, rootfs_dir, strlist[8], strlist[10]) 1560d163575Sopenharmony_ci res = commands.getoutput(cmd) 1570d163575Sopenharmony_ci res = res.split('\n') 1580d163575Sopenharmony_ci print("<%.2d>%s<%s><%s>" % (index, res[0], strlist[10], strlist[8])) 1590d163575Sopenharmony_ci index = index + 1 1600d163575Sopenharmony_ci 1610d163575Sopenharmony_cidef parse_user_exc(excinfo_file, rootfs_dir, addr2line_cmd, objdump_cmd): 1620d163575Sopenharmony_ci #parse pc ulr 1630d163575Sopenharmony_ci ret1 = parse_user_pc_ulr(excinfo_file, rootfs_dir, 'pc', addr2line_cmd, objdump_cmd) 1640d163575Sopenharmony_ci ret2 = parse_user_pc_ulr(excinfo_file, rootfs_dir, 'ulr', addr2line_cmd, objdump_cmd) 1650d163575Sopenharmony_ci #parse lr 1660d163575Sopenharmony_ci parse_user_lr(excinfo_file, rootfs_dir, addr2line_cmd) 1670d163575Sopenharmony_ci return ret1 and ret2 1680d163575Sopenharmony_ci 1690d163575Sopenharmony_cidef parse_backtrace(backtrace_file, ohos_image_file, addr2line_cmd): 1700d163575Sopenharmony_ci with open(backtrace_file, 'r+') as f: 1710d163575Sopenharmony_ci find = -1 1720d163575Sopenharmony_ci start = 0 1730d163575Sopenharmony_ci index = 1 1740d163575Sopenharmony_ci for lines in f.readlines(): 1750d163575Sopenharmony_ci if 'backtrace begin' in lines: 1760d163575Sopenharmony_ci if start == 1: 1770d163575Sopenharmony_ci break 1780d163575Sopenharmony_ci start = 1 1790d163575Sopenharmony_ci if start and 'lr =' in lines: 1800d163575Sopenharmony_ci lines = lines[lines.find('lr ='):] 1810d163575Sopenharmony_ci strlist = lines.split() 1820d163575Sopenharmony_ci cmd = "%s%s %s" % (addr2line_cmd, ohos_image_file, strlist[2]) 1830d163575Sopenharmony_ci ret = commands.getoutput(cmd) 1840d163575Sopenharmony_ci ret = ret.split('\n') 1850d163575Sopenharmony_ci print("\n<%.2d>%s<%s>" % (index, ret[0], strlist[2])) 1860d163575Sopenharmony_ci index = index + 1 1870d163575Sopenharmony_ci find = 0 1880d163575Sopenharmony_ci 1890d163575Sopenharmony_ci return find 1900d163575Sopenharmony_ci 1910d163575Sopenharmony_cidef parse_excinfo(excinfo_file, ohos_image_file, rootfs_dir, addr2line_cmd, objdump_cmd): 1920d163575Sopenharmony_ci cmd = "dos2unix %s" % (excinfo_file) 1930d163575Sopenharmony_ci commands.getoutput(cmd) 1940d163575Sopenharmony_ci kernel_exc = is_kernel_exc(excinfo_file) 1950d163575Sopenharmony_ci user_exc = is_user_exc(excinfo_file) 1960d163575Sopenharmony_ci 1970d163575Sopenharmony_ci if kernel_exc == False and user_exc == False: 1980d163575Sopenharmony_ci if parse_backtrace(excinfo_file, ohos_image_file, addr2line_cmd) != 0: 1990d163575Sopenharmony_ci print("%s is not a excinfo or backtrace file\n"%excinfo_file) 2000d163575Sopenharmony_ci return -1 2010d163575Sopenharmony_ci else: 2020d163575Sopenharmony_ci return 0 2030d163575Sopenharmony_ci if user_exc: 2040d163575Sopenharmony_ci if rootfs_dir != None: 2050d163575Sopenharmony_ci return parse_user_exc(excinfo_file, rootfs_dir, addr2line_cmd, objdump_cmd) 2060d163575Sopenharmony_ci else: 2070d163575Sopenharmony_ci print('error: rootfs_dir is none') 2080d163575Sopenharmony_ci return -1 2090d163575Sopenharmony_ci return parse_kernel_exc(excinfo_file, ohos_image_file, addr2line_cmd, objdump_cmd) 2100d163575Sopenharmony_ci 2110d163575Sopenharmony_cidef parse_compiler(compiler): 2120d163575Sopenharmony_ci addr2line = '' 2130d163575Sopenharmony_ci addr2line_cmd = '' 2140d163575Sopenharmony_ci objdump = '' 2150d163575Sopenharmony_ci objdump_cmd = '' 2160d163575Sopenharmony_ci cmd = "which %s" % (compiler) 2170d163575Sopenharmony_ci ret = commands.getoutput(cmd) 2180d163575Sopenharmony_ci if ret == '': 2190d163575Sopenharmony_ci print('%s is not exist'%compiler) 2200d163575Sopenharmony_ci return None 2210d163575Sopenharmony_ci index1 = ret.rfind('gcc') 2220d163575Sopenharmony_ci index2 = ret.rfind('clang') 2230d163575Sopenharmony_ci if index1 != -1: 2240d163575Sopenharmony_ci addr2line = ret[0:index1] + 'addr2line' 2250d163575Sopenharmony_ci objdump = ret[0:index1] + 'objdump' 2260d163575Sopenharmony_ci elif index2 != -1: 2270d163575Sopenharmony_ci index3 = ret.rfind('/') 2280d163575Sopenharmony_ci addr2line = ret[0:index3 + 1] + 'llvm-addr2line' 2290d163575Sopenharmony_ci objdump = ret[0:index3 + 1] + 'llvm-objdump' 2300d163575Sopenharmony_ci else: 2310d163575Sopenharmony_ci print('%s is not arm-xxx-xxx-gcc or clang'%compiler) 2320d163575Sopenharmony_ci return None 2330d163575Sopenharmony_ci addr2line_cmd = addr2line + ' -C -f -e ' 2340d163575Sopenharmony_ci objdump_cmd = objdump + ' -d ' 2350d163575Sopenharmony_ci return [addr2line_cmd, objdump_cmd] 2360d163575Sopenharmony_ci 2370d163575Sopenharmony_cidef main(): 2380d163575Sopenharmony_ci parser = argparse.ArgumentParser() 2390d163575Sopenharmony_ci parser.add_argument('--f', help = 'excinfo file or backtrace file') 2400d163575Sopenharmony_ci parser.add_argument('--e', help = 'elf system image file') 2410d163575Sopenharmony_ci parser.add_argument('--r', help = 'the path of rootfs') 2420d163575Sopenharmony_ci parser.add_argument('--c', help = 'compiler [arm-xxx-xxx-gcc/clang]') 2430d163575Sopenharmony_ci args = parser.parse_args() 2440d163575Sopenharmony_ci 2450d163575Sopenharmony_ci if args.f == None or args.e == None: 2460d163575Sopenharmony_ci print("input error\n") 2470d163575Sopenharmony_ci parser.print_help() 2480d163575Sopenharmony_ci return -1 2490d163575Sopenharmony_ci 2500d163575Sopenharmony_ci excinfo_file = args.f 2510d163575Sopenharmony_ci ohos_image_file = args.e 2520d163575Sopenharmony_ci rootfs_dir = args.r 2530d163575Sopenharmony_ci 2540d163575Sopenharmony_ci addr2line_cmd = 'llvm-addr2line -C -f -e ' 2550d163575Sopenharmony_ci objdump_cmd = 'llvm-objdump -d ' 2560d163575Sopenharmony_ci if args.c != None: 2570d163575Sopenharmony_ci cmd = parse_compiler(args.c) 2580d163575Sopenharmony_ci if cmd == None: 2590d163575Sopenharmony_ci return -1 2600d163575Sopenharmony_ci addr2line_cmd = cmd[0] 2610d163575Sopenharmony_ci objdump_cmd = cmd[1] 2620d163575Sopenharmony_ci return parse_excinfo(excinfo_file, ohos_image_file, rootfs_dir, addr2line_cmd, objdump_cmd) 2630d163575Sopenharmony_ci 2640d163575Sopenharmony_ciif __name__ == "__main__": 2650d163575Sopenharmony_ci sys.exit(main()) 266