From 75df02f7a3e1b6d0ad13ee50758da33806ab2fa9 Mon Sep 17 00:00:00 2001 From: Jeremy Rifkin <51220084+jeremy-rifkin@users.noreply.github.com> Date: Sun, 23 Jul 2023 10:24:28 -0400 Subject: [PATCH] Fix bug in the test ci script (#15) --- ci/test-all-configs.py | 5 +++-- src/symbols/symbols_with_addr2line.cpp | 24 ++++++++++++++---------- test/expected/macos.addr2line.txt | 25 +++++++++++++++++++++++++ 3 files changed, 42 insertions(+), 12 deletions(-) create mode 100644 test/expected/macos.addr2line.txt diff --git a/ci/test-all-configs.py b/ci/test-all-configs.py index 2276f5e..7bcd4ac 100644 --- a/ci/test-all-configs.py +++ b/ci/test-all-configs.py @@ -100,6 +100,7 @@ def output_matches(output: str, params: Tuple[str]): return not errored def run_command(*args: List[str]): + global failed print(f"{Fore.CYAN}{Style.BRIGHT}Running Command \"{' '.join(args)}\"{Style.RESET_ALL}") p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = p.communicate() @@ -110,7 +111,6 @@ def run_command(*args: List[str]): print(stdout.decode("utf-8"), end="") print("stderr:") print(stderr.decode("utf-8"), end="") - global failed failed = True return False else: @@ -118,6 +118,7 @@ def run_command(*args: List[str]): return True def run_test(test_binary, params: Tuple[str]): + global failed print(f"{Fore.CYAN}{Style.BRIGHT}Running test{Style.RESET_ALL}") test = subprocess.Popen([test_binary], stdout=subprocess.PIPE, stderr=subprocess.PIPE) test_stdout, test_stderr = test.communicate() @@ -129,6 +130,7 @@ def run_test(test_binary, params: Tuple[str]): print(test_stderr.decode("utf-8"), end="") print("stdout:") print(test_stdout.decode("utf-8"), end="") + failed = True else: if len(test_stderr) != 0: print("stderr:") @@ -137,7 +139,6 @@ def run_test(test_binary, params: Tuple[str]): print(f"{Fore.GREEN}{Style.BRIGHT}Test succeeded{Style.RESET_ALL}") else: print(f"{Fore.RED}{Style.BRIGHT}Test failed{Style.RESET_ALL}") - global failed failed = True def build(matrix): diff --git a/src/symbols/symbols_with_addr2line.cpp b/src/symbols/symbols_with_addr2line.cpp index 27596f2..1d01f4b 100644 --- a/src/symbols/symbols_with_addr2line.cpp +++ b/src/symbols/symbols_with_addr2line.cpp @@ -262,14 +262,18 @@ namespace cpptrace { std::unordered_map entries; for(std::size_t i = 0; i < dlframes.size(); i++) { const auto& entry = dlframes[i]; - ///fprintf(stderr, "%s %s\n", to_hex(entry.raw_address).c_str(), to_hex(entry.raw_address - entry.obj_base + base).c_str()); - entries[entry.obj_path].emplace_back( - to_hex(entry.raw_address - entry.obj_base + get_module_image_base(entry)), - trace[i] - ); - // Set what is known for now, and resolutions from addr2line should overwrite - trace[i].filename = entry.obj_path; - trace[i].symbol = entry.symbol; + // If libdl fails to find the shared object for a frame, the path will be empty. I've observed this + // on macos when looking up the shared object containing `start`. + if(!entry.obj_path.empty()) { + ///fprintf(stderr, "%s %s\n", to_hex(entry.raw_address).c_str(), to_hex(entry.raw_address - entry.obj_base + base).c_str()); + entries[entry.obj_path].emplace_back( + to_hex(entry.raw_address - entry.obj_base + get_module_image_base(entry)), + trace[i] + ); + // Set what is known for now, and resolutions from addr2line should overwrite + trace[i].filename = entry.obj_path; + trace[i].symbol = entry.symbol; + } } return entries; } @@ -329,7 +333,7 @@ namespace cpptrace { obj_end != std::string::npos, "Unexpected edge case while processing addr2line/atos output" ); - const std::size_t filename_start = line.find(") (", obj_end) + 3; + const std::size_t filename_start = line.find(") (", obj_end); if(filename_start == std::string::npos) { // presumably something like 0x100003b70 (in demo) or foo (in bar) + 14 return; @@ -339,7 +343,7 @@ namespace cpptrace { filename_end != std::string::npos, "Unexpected edge case while processing addr2line/atos output" ); - entries_vec[entry_index].second.get().filename = line.substr(filename_start, filename_end - filename_start); + entries_vec[entry_index].second.get().filename = line.substr(filename_start + 3, filename_end - filename_start - 3); const std::size_t line_start = filename_end + 1; const std::size_t line_end = line.find(")", filename_end); internal_verify( diff --git a/test/expected/macos.addr2line.txt b/test/expected/macos.addr2line.txt new file mode 100644 index 0000000..046b968 --- /dev/null +++ b/test/expected/macos.addr2line.txt @@ -0,0 +1,25 @@ +test.cpp||19||trace() +test.cpp||35||foo(int) +test.cpp||39||foo(int) +test.cpp||39||foo(int) +test.cpp||39||foo(int) +test.cpp||39||foo(int) +test.cpp||39||foo(int) +test.cpp||39||foo(int) +test.cpp||39||foo(int) +test.cpp||39||foo(int) +test.cpp||39||foo(int) +test.cpp||39||foo(int) +test.cpp||47||void foo(int, int) +test.cpp||47||void foo(int, int, int) +test.cpp||47||void foo(int, int, int, int) +test.cpp||47||void foo(int, int, int, int, int) +test.cpp||47||void foo(int, int, int, int, int, int) +test.cpp||47||void foo(int, int, int, int, int, int, int) +test.cpp||47||void foo(int, int, int, int, int, int, int, int) +test.cpp||47||void foo(int, int, int, int, int, int, int, int, int) +test.cpp||47||void foo(int, int, int, int, int, int, int, int, int, int) +test.cpp||53||function_two(int, float) +test.cpp||59||function_one(int) +test.cpp||65||main +||0|| \ No newline at end of file