SERVER-115169 core-analyzer: only parse dwarf versions from compile units we create (#45029)

GitOrigin-RevId: af9e569444e664b47c9af67998c716b337451754
This commit is contained in:
Sean Lyons 2025-12-15 16:26:07 -05:00 committed by MongoDB Bot
parent 4a98810406
commit 550cf43403
3 changed files with 116 additions and 5 deletions

View File

@ -203,6 +203,36 @@ def download_multiversion_artifact(
return False return False
def get_dwarf_version(dwarf_dump):
"""
Find the dwarf version of a compile unit that was produced by a MongoDB compiler or
has mongodb sources in its name.
See a segment of a dwarf dump in buildscripts/tests/resmokelib/hang_analyzer/test_extractor.py
"""
# Checks if a compile unit contains "mongo" or "src/third_party".
# The DW_AT_producer tag will contain the compiler used, which may be stamped with 'MongoDB' for our
# toolchain compilers.
# The DW_AT_name can contain the source file, for which we hope to find 'src/mongo' or 'src/third_party'
mongo_pattern = r"mongo|src/third_party"
version_pattern = r"version = 0x([0-9]{4}),"
for unit in dwarf_dump.split("Compile Unit"):
if re.search(mongo_pattern, unit, re.IGNORECASE):
matches = re.search(version_pattern, unit)
if matches:
return int(matches.group(1))
# If we didn't find any compile unit that looks like the patterns, fallback to ANY dwarf version
# listed in the output.
matches = re.search(version_pattern, dwarf_dump)
if matches:
return int(matches.group(1))
return None
@TRACER.start_as_current_span("core_analyzer.post_install_gdb_optimization") @TRACER.start_as_current_span("core_analyzer.post_install_gdb_optimization")
def post_install_gdb_optimization(download_dir: str, root_looger: Logger): def post_install_gdb_optimization(download_dir: str, root_looger: Logger):
@TRACER.start_as_current_span("core_analyzer.post_install_gdb_optimization.add_index") @TRACER.start_as_current_span("core_analyzer.post_install_gdb_optimization.add_index")
@ -228,9 +258,10 @@ def post_install_gdb_optimization(download_dir: str, root_looger: Logger):
current_span.set_attribute("add_index_status", "skipped") current_span.set_attribute("add_index_status", "skipped")
return return
# find dwarf version from output, it should always be present version = get_dwarf_version(process.stdout)
regex = re.search("version = 0x([0-9]{4}),", process.stdout) if version:
if not regex: current_span.set_attribute("dwarf_version", version)
else:
current_span.set_status(StatusCode.ERROR, "Could not find dwarf version in file.") current_span.set_status(StatusCode.ERROR, "Could not find dwarf version in file.")
current_span.set_attributes( current_span.set_attributes(
{ {
@ -243,9 +274,7 @@ def post_install_gdb_optimization(download_dir: str, root_looger: Logger):
return return
raise RuntimeError(f"Could not find dwarf version in file {file_path}") raise RuntimeError(f"Could not find dwarf version in file {file_path}")
version = int(regex.group(1))
target_dir = os.path.dirname(file_path) target_dir = os.path.dirname(file_path)
current_span.set_attribute("dwarf_version", version)
try: try:
# logic copied from https://sourceware.org/gdb/onlinedocs/gdb/Index-Files.html # logic copied from https://sourceware.org/gdb/onlinedocs/gdb/Index-Files.html

View File

@ -41,3 +41,14 @@ py_test(
), ),
], ],
) )
py_test(
name = "test_extractor",
srcs = [
"test_extractor.py",
],
deps = [
"//buildscripts/resmokelib",
"//buildscripts/resmokelib/hang_analyzer",
],
)

View File

@ -0,0 +1,71 @@
import unittest
from buildscripts.resmokelib.hang_analyzer.extractor import get_dwarf_version
class TestExtractor(unittest.TestCase):
def test_find_dwarf_version(self):
"""
Test that DWARF version 5 is identified based on "format = DWARF32, version = 0x0005", and
that the compile unit for the system library with DWARF version 2 is ignored.
"""
# This is an excerpt from `llvm-dwarfdump -r 0 dist-test/bin/mongod.debug`
dwarf_dump = """
dist-test/bin/mongod.debug: file format elf64-x86-64
.debug_info contents:
0x00000000: Compile Unit: length = 0x00000041, format = DWARF32, version = 0x0002, abbr_offset = 0x0000, addr_size = 0x08 (next unit at 0x00000045)
0x0000000b: DW_TAG_compile_unit
DW_AT_stmt_list (0x00000000)
DW_AT_low_pc (0x00000000042e7200)
DW_AT_high_pc (0x00000000042e722b)
DW_AT_name ("../sysdeps/x86_64/start.S")
DW_AT_comp_dir ("/home/abuild/rpmbuild/BUILD/glibc-2.31/csu")
DW_AT_producer ("GNU AS 2.43.1")
DW_AT_language (DW_LANG_Mips_Assembler)
0x00000045: Compile Unit: length = 0x0000003b, format = DWARF32, version = 0x0004, abbr_offset = 0x0021, addr_size = 0x08 (next unit at 0x00000084)
0x00000050: DW_TAG_compile_unit
DW_AT_producer ("GNU C11 7.5.0 -mtune=generic -march=x86-64 -g -g -O2 -std=gnu11 -fgnu89-inline -fmessage-length=0 -funwind-tables -fasynchronous-unwind-tables -fstack-clash-protection -fmerge-all-constants -frounding-math -fstack-protector-strong -fpatchable-function-entry=16,14 -fmath-errno -fno-stack-protector -ftls-model=initial-exec -fPIE")
DW_AT_language (DW_LANG_C99)
DW_AT_name ("init.c")
DW_AT_comp_dir ("/home/abuild/rpmbuild/BUILD/glibc-2.31/csu")
DW_AT_stmt_list (0x00000059)
0x00000084: Compile Unit: length = 0x0000001e, format = DWARF32, version = 0x0002, abbr_offset = 0x0054, addr_size = 0x08 (next unit at 0x000000a6)
0x0000008f: DW_TAG_compile_unit
DW_AT_stmt_list (0x00000080)
DW_AT_ranges (0x00000000
[0x000000000680fe04, 0x000000000680fe16)
[0x000000000680fe1c, 0x000000000680fe20))
DW_AT_name ("../sysdeps/x86_64/crti.S")
DW_AT_comp_dir ("/home/abuild/rpmbuild/BUILD/glibc-2.31/csu")
DW_AT_producer ("GNU AS 2.43.1")
DW_AT_language (DW_LANG_Mips_Assembler)
0x000000a6: Compile Unit: length = 0x0000445e, format = DWARF32, version = 0x0005, unit_type = DW_UT_compile, abbr_offset = 0x0066, addr_size = 0x08 (next unit at 0x00004508)
0x000000b2: DW_TAG_compile_unit
DW_AT_producer ("MongoDB clang version 19.1.7 (https://x-access-token:ghs_abc123@github.com/10gen/toolchain-builder.git 868b3c714c67f4f245623d2f772d0fac95d936a2)")
DW_AT_language (DW_LANG_C_plus_plus_14)
DW_AT_name ("src/mongo/db/mongod.cpp")
DW_AT_str_offsets_base (0x00000008)
DW_AT_stmt_list (0x000000e2)
DW_AT_comp_dir (".")
DW_AT_low_pc (0x0000000000000000)
DW_AT_ranges (indexed (0x0) rangelist = 0x00000010
[0x0000000003b0ddb0, 0x0000000003b0ddc0)
[0x0000000003b0ddc0, 0x0000000003b0ddc9)
[0x0000000003b0b6ad, 0x0000000003b0b6d4)
[0x0000000003b0b6e0, 0x0000000003b0b71f))
DW_AT_addr_base (0x00000008)
DW_AT_rnglists_base (0x0000000c)
DW_AT_loclists_base (0x0000000c)
"""
self.assertEqual(get_dwarf_version(dwarf_dump), 5)
if __name__ == "__main__":
unittest.main()