From c3e8617521ad03d7b554d68a5ab9dce6b274c2b5 Mon Sep 17 00:00:00 2001 From: Jesse Schwartzentruber Date: Fri, 11 Jul 2025 14:58:57 -0400 Subject: [PATCH] [compiler-rt] Fix frame numbering for unparsable frames. This can happen when JIT code is run, and we can't symbolize those frames, but they should remain numbered in the stack. --- .../lib/asan/scripts/asan_symbolize.py | 47 ++++++++++++------- 1 file changed, 30 insertions(+), 17 deletions(-) diff --git a/compiler-rt/lib/asan/scripts/asan_symbolize.py b/compiler-rt/lib/asan/scripts/asan_symbolize.py index 058a1614b55e6..e70f987f03fe6 100755 --- a/compiler-rt/lib/asan/scripts/asan_symbolize.py +++ b/compiler-rt/lib/asan/scripts/asan_symbolize.py @@ -22,7 +22,6 @@ import argparse import bisect import errno -import getopt import logging import os import re @@ -38,6 +37,7 @@ allow_system_symbolizer = True force_system_symbolizer = False + # FIXME: merge the code that calls fix_filename(). def fix_filename(file_name): if fix_filename_patterns: @@ -507,20 +507,29 @@ def symbolize_address(self, addr, binary, offset, arch): assert result return result - def get_symbolized_lines(self, symbolized_lines, inc_frame_counter=True): + def get_symbolized_lines(self, symbolized_lines): if not symbolized_lines: - if inc_frame_counter: - self.frame_no += 1 - return [self.current_line] - else: - assert inc_frame_counter - result = [] - for symbolized_frame in symbolized_lines: - result.append( - " #%s %s" % (str(self.frame_no), symbolized_frame.rstrip()) + # If it is an unparsable frame, but contains a frame counter and address + # replace the frame counter so the stack is still consistent. + unknown_stack_frame_format = r"^( *#([0-9]+) +)(0x[0-9a-f]+) +.*" + match = re.match(unknown_stack_frame_format, self.current_line) + if match: + rewritten_line = ( + self.current_line[: match.start(2)] + + str(self.frame_no) + + self.current_line[match.end(2) :] ) self.frame_no += 1 - return result + return [rewritten_line] + # Not a frame line so don't increment the frame counter. + return [self.current_line] + result = [] + for symbolized_frame in symbolized_lines: + result.append( + " #%s %s" % (str(self.frame_no), symbolized_frame.rstrip()) + ) + self.frame_no += 1 + return result def process_logfile(self): self.frame_no = 0 @@ -546,8 +555,7 @@ def process_line_posix(self, line): match = re.match(stack_trace_line_format, line) if not match: logging.debug('Line "{}" does not match regex'.format(line)) - # Not a frame line so don't increment the frame counter. - return self.get_symbolized_lines(None, inc_frame_counter=False) + return self.get_symbolized_lines(None) logging.debug(line) _, frameno_str, addr, binary, offset = match.groups() @@ -603,6 +611,7 @@ def _load_plugin_from_file_impl_py_gt_2(self, file_path, globals_space): def load_plugin_from_file(self, file_path): logging.info('Loading plugins from "{}"'.format(file_path)) globals_space = dict(globals()) + # Provide function to register plugins def register_plugin(plugin): logging.info("Registering plugin %s", plugin.get_name()) @@ -779,9 +788,13 @@ def __str__(self): arch=self.arch, start_addr=self.start_addr, end_addr=self.end_addr, - module_path=self.module_path - if self.module_path == self.module_path_for_symbolization - else "{} ({})".format(self.module_path_for_symbolization, self.module_path), + module_path=( + self.module_path + if self.module_path == self.module_path_for_symbolization + else "{} ({})".format( + self.module_path_for_symbolization, self.module_path + ) + ), uuid=self.uuid, )