Files
llvm-project/lldb/test/API/lang/cpp/function-call-from-object-file/TestFunctionCallFromObjectFile.py
Michael Buch 332b4deb0d [lldb][IRExecutionUnit] Return error on failure to resolve function address (#161363)
Starting with https://github.com/llvm/llvm-project/pull/148877 we
started encoding the module ID of the function DIE we are currently
parsing into its `AsmLabel` in the AST. When the JIT asks LLDB to
resolve our special mangled name, we would locate the module and resolve
the function/symbol we found in it.

If we are debugging with a `SymbolFileDWARFDebugMap`, the module ID we
encode is that of the `.o` file that is tracked by the debug-map. To
resolve the address of the DIE in that `.o` file, we have to ask
`SymbolFileDWARFDebugMap::LinkOSOAddress` to turn the address of the
`.o` DIE into a real address in the linked executable. This will only
work if the `.o` address was actually tracked by the debug-map. However,
if the function definition appears in multiple `.o` files (which is the
case for functions defined in headers), the linker will most likely
de-deuplicate that definition. So most `.o`'s definition DIEs for that
function won't have a contribution in the debug-map, and thus we fail to
resolve the address.

When debugging Clang on Darwin, e.g., you'd see:
```
(lldb) expr CXXDecl->getName()

error: Couldn't look up symbols:
  $__lldb_func::0x1:0x4000d000002359da:_ZNK5clang9NamedDecl7getNameEv
Hint: The expression tried to call a function that is not present in the target, perhaps because it was optimized out by the compiler.
```
unless you were stopped in the `.o` file whose definition of `getName`
made it into the final executable.

The fix here is to error out if we fail to resolve the address, causing
us to fall back on the old flow which did a lookup by mangled name,
which the `SymbolFileDWARFDebugMap` will handle correctly.

An alternative fix to this would be to encode the
`SymbolFileDWARFDebugMap`'s module-id. And implement
`SymbolFileDWARFDebugMap::ResolveFunctionCallLabel` by doing a mangled
name lookup. The proposed approach doesn't stop us from implementing
that, so we could choose to do it in a follow-up.

rdar://161393045
2025-10-01 08:37:15 +01:00

30 lines
1.1 KiB
Python

"""
Tests that we can call functions that have definitions in multiple
CUs in the debug-info (which is the case for functions defined in headers).
The linker will most likely de-duplicate the functiond definitions when linking
the final executable. On Darwin, this will create a debug-map that LLDB will use
to fix up object file addresses to addresses in the linked executable. However,
if we parsed the DIE from the object file whose functiond definition got stripped
by the linker, LLDB needs to ensure it can still resolve the function symbol it
got for it.
"""
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
class TestFunctionCallFromObjectFile(TestBase):
def test_lib1(self):
self.build()
lldbutil.run_to_name_breakpoint(self, "lib1_func")
self.expect_expr("Foo{}.foo()", result_type="int", result_value="15")
def test_lib2(self):
self.build()
lldbutil.run_to_name_breakpoint(self, "lib2_func")
self.expect_expr("Foo{}.foo()", result_type="int", result_value="15")