Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(58)

Side by Side Diff: third_party/android_platform/development/scripts/stack_libs.py

Issue 1407143010: Revert of stack: Adjust Pre-M Android incorrect debuggerd addresses. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 #!/usr/bin/env python
2 #
3 # Copyright (c) 2015 The Chromium Authors. All rights reserved.
4 # Use of this source code is governed by a BSD-style license that can be
5 # found in the LICENSE file.
6
7
8 """Identifies address adjustments required for native crash dumps."""
9
10 import glob
11 import os.path
12 import subprocess
13
14
15 _BASE_APK = 'base.apk'
16 _LIBCHROME_SO = 'libchrome.so'
17
18
19 def GetTargetAndroidVersionNumber(lines):
20 """Return the Android major version number from the build fingerprint.
21
22 Args:
23 lines: Lines read from the tombstone file, before preprocessing.
24 Returns:
25 5, 6, etc, or None if not determinable (developer build?)
26 """
27 # For example, "Build fingerprint: 'Android/aosp_flo/flo:5.1.1/...'" is 5.
28 for line in lines:
29 if line.startswith('Build fingerprint: '):
30 fingerprint = line.split()[2]
31 version = fingerprint.split('/')[2].split(':')[1].split('.')[0]
32 try:
33 return int(version)
34 except ValueError:
35 return None
36 return None
37
38
39 def _HasElfHeader(path):
40 """Return True if the file at the given path has an ELF magic header.
41
42 Minimal check only, for 'ELF' in bytes 1 to 3 of the file. Filters out
43 the zero-byte false-positives such as libchromeview.so returned by glob.
44
45 Args:
46 path: Path to file to check.
47 Returns:
48 True or False
49 """
50 with open(path) as stream:
51 elf_header = stream.read(4)
52 return len(elf_header) == 4 and elf_header[1:4] == 'ELF'
53
54
55 def _ReadElfProgramHeaders(lib):
56 """Return an iterable of program headers, from 'readelf -l ...'.
57
58 Uses the platform readelf in all cases. This is somewhat lazy, but suffices
59 in practice because program headers in ELF files are architecture-agnostic.
60
61 Args:
62 lib: Library file to read.
63 Returns:
64 [readelf -l output line, ...]
65 """
66 string = subprocess.check_output(['readelf', '-l', lib])
67 return string.split('\n')
68
69
70 def _FindMinLoadVaddr(lib):
71 """Return the minimum VirtAddr field of all library LOAD segments.
72
73 Args:
74 lib: Library file to read.
75 Returns:
76 Min VirtAddr field for all LOAD segments, or 0 if none found.
77 """
78 vaddrs = []
79 # Locate LOAD lines and find the smallest VirtAddr field, eg:
80 # Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
81 # LOAD 0x000000 0x001d6000 0x001d6000 0x20f63fc 0x20f63fc R E 0x1000
82 # LOAD 0x20f6970 0x022cd970 0x022cd970 0x182df8 0x1b4490 RW 0x1000
83 # would return 0x1d6000. Ignores all non-LOAD lines.
84 for line in _ReadElfProgramHeaders(lib):
85 elements = line.split()
86 if elements and elements[0] == 'LOAD':
87 vaddrs.append(int(elements[2], 16))
88 if vaddrs:
89 return min(vaddrs)
90 return 0
91
92
93 def GetLoadVaddrs(apk_dir):
94 """Return a dictionary of minimum VirtAddr fields for libraries in apk_dir.
95
96 The dictionary returned may be passed to stack_core.ConvertTrace(). In
97 pre-M Android releases the addresses printed by debuggerd into tombstones
98 do not take account of non-zero vaddrs. Here we collect this information,
99 so that we can use it later to correct such debuggerd tombstones.
100
101 Args:
102 apk_dir: Path to APK staging directory.
103 Returns:
104 {'libchrome.so': 12345, ...}
105 """
106 pathname = apk_dir + '/libs/*/*.so'
107 libs = [lib for lib in glob.glob(pathname) if _HasElfHeader(lib)]
108
109 load_vaddrs = {}
110 for lib in libs:
111 min_vaddr = _FindMinLoadVaddr(lib)
112 if min_vaddr:
113 # Store with the library basename as the key. This is because once on
114 # the device its path may not fully match its place in the APK staging
115 # directory
116 load_vaddrs[os.path.basename(lib)] = min_vaddr
117
118 # Direct load from APK causes debuggerd to tag trace lines as if from the
119 # file .../base.apk. So if we encounter a libchrome.so with packed
120 # relocations, replicate this as base.apk so that later adjustment code
121 # finds the appropriate adjustment.
122 if _LIBCHROME_SO in load_vaddrs:
123 load_vaddrs[_BASE_APK] = load_vaddrs[_LIBCHROME_SO]
124
125 return load_vaddrs
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698