Fix the stack decoder.
Trying to decode a stack with a dex pc frame which comes from an
apk, the script throws a number of errors. Fix those errors.
Bug: 356896129
Test: Ran a backtrace with an apk and verified it properly shows the right
Test: file and doesn't emit any crashes.
Change-Id: I883e72e71d97b44c57d82664e6198d40164478a0
diff --git a/scripts/stack_core.py b/scripts/stack_core.py
index 8ab5520..7ed0e40 100755
--- a/scripts/stack_core.py
+++ b/scripts/stack_core.py
@@ -307,6 +307,12 @@
name = match.group(1)
start = int(match.group(2))
end = start + int(match.group(3))
+ # When the actual apk data is mapped in to the process, it will be
+ # mapped in on a page boundary. This means the header data can start
+ # after the actual offset and the code will get the wrong file.
+ # Rounding down to a page boundary (assumes 4096 page size) fixes
+ # this problem.
+ start = start & ~0xfff
offset_list.append([name, start, end])
return name, start, end
@@ -553,6 +559,7 @@
# Some.apk!libshared.so
# or
# Some.apk
+ lib_extracted = False
if so_offset:
# If it ends in apk, we are done.
apk = None
@@ -572,6 +579,7 @@
apk = area[0:index + 4]
if apk:
lib_name, lib = self.GetLibFromApk(apk, so_offset)
+ lib_extracted = lib != None
else:
# Sometimes we'll see something like:
# #01 pc abcd libart.so!libart.so
@@ -583,17 +591,18 @@
lib = area
lib_name = None
- if build_id:
- # If we have the build_id, do a brute-force search of the symbols directory.
- basename = os.path.basename(lib).split("!")[-1]
- lib = self.GetLibraryByBuildId(symbol.SYMBOLS_DIR, basename, build_id)
- if not lib:
- print("WARNING: Cannot find {} with build id {} in symbols directory."
- .format(basename, build_id))
- else:
- # When using atest, test paths are different between the out/ directory
- # and device. Apply fixups.
- lib = self.GetLibPath(lib)
+ if not lib_extracted:
+ if build_id:
+ # If we have the build_id, do a brute-force search of the symbols directory.
+ basename = os.path.basename(lib).split("!")[-1]
+ lib = self.GetLibraryByBuildId(symbol.SYMBOLS_DIR, basename, build_id)
+ if not lib:
+ print("WARNING: Cannot find {} with build id {} in symbols directory."
+ .format(basename, build_id))
+ else:
+ # When using atest, test paths are different between the out/ directory
+ # and device. Apply fixups.
+ lib = self.GetLibPath(lib)
# If a calls b which further calls c and c is inlined to b, we want to
# display "a -> b -> c" in the stack trace instead of just "a -> c"
diff --git a/scripts/symbol.py b/scripts/symbol.py
index 505677c..99e60c6 100755
--- a/scripts/symbol.py
+++ b/scripts/symbol.py
@@ -105,12 +105,14 @@
return pipe
def SpawnProcess(self, cmd):
- return subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, universal_newlines=True)
+ return subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, universal_newlines=True)
def TerminateProcess(self, pipe):
- pipe.stdin.close()
- pipe.stdout.close()
- pipe.terminate()
+ if pipe.poll() is None:
+ # Process is still running.
+ pipe.stdin.close()
+ pipe.stdout.close()
+ pipe.terminate()
pipe.wait()
def KillAllProcesses(self):
@@ -304,7 +306,7 @@
frame_offset, size, tag_offset may be None.
"""
child = _GetJSONSymbolizerForLib(lib)
- if child is None:
+ if child is None or child.poll() is not None:
return None
records = []
for addr in unique_addrs:
@@ -374,11 +376,12 @@
child.stdin.flush()
records = []
json_result = json.loads(child.stdout.readline().strip())
- for symbol in json_result["Symbol"]:
- function_name = symbol["FunctionName"]
- # GNU style location: file_name:line_num
- location = ("%s:%s" % (symbol["FileName"], symbol["Line"]))
- records.append((function_name, location))
+ if "Symbol" in json_result:
+ for symbol in json_result["Symbol"]:
+ function_name = symbol["FunctionName"]
+ # GNU style location: file_name:line_num
+ location = ("%s:%s" % (symbol["FileName"], symbol["Line"]))
+ records.append((function_name, location))
except IOError as e:
# Remove the / in front of the library name to match other output.
records = [(None, lib[1:] + " ***Error: " + str(e))]