swiftlang / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies. This fork is used to manage Swift’s stable releases of Clang as well as support the Swift project.
https://llvm.org
Other
1.12k stars 332 forks source link

[lldb][ObjC] Fix method list entry offset calculation (#115571) #9570

Closed JDevlieghere closed 1 week ago

JDevlieghere commented 2 weeks ago

The relative_list_list_entry_t offset field in the Objective-C runtime is of type int64_t. There are cases where these offsets are negative values. For negative offsets, LLDB would currently incorrectly zero-extend the offset (dropping the fact that the offset was negative), instead producing large offsets that, when added to the m_baseMethods_ptr result in addresses that had their upper bits set (e.g., 0x00017ff81b3241b0). We then would try to GetMethodList from such an address but fail to read it (because it's an invalid address). This would manifest in Objective-C decls not getting completed correctly (and formatters not working). We noticed this in CI failures on our Intel bots. This happened to work fine on arm64 because we strip the upper bits when calling ClassDescriptorV2::method_list_t::Read using the FixCodeAddress ABI plugin API (which doesn't do that on Intel).

The fix is to sign-extend the offset calculation.

Example failure before this patch:


======================================================================
FAIL: test_break_dwarf (TestRuntimeTypes.RuntimeTypesTestCase)
   Test setting objc breakpoints using '_regexp-break' and 'breakpoint set'.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/michaelbuch/Git/llvm-project/lldb/packages/Python/lldbsuite/test/lldbtest.py", line 1769, in test_method
    return attrvalue(self)
  File "/Users/michaelbuch/Git/llvm-project/lldb/test/API/lang/objc/foundation/TestRuntimeTypes.py", line 48, in test_break
    self.expect(
  File "/Users/michaelbuch/Git/llvm-project/lldb/packages/Python/lldbsuite/test/lldbtest.py", line 2370, in expect
    self.runCmd(
  File "/Users/michaelbuch/Git/llvm-project/lldb/packages/Python/lldbsuite/test/lldbtest.py", line 1000, in runCmd
    self.assertTrue(self.res.Succeeded(), msg + output)
AssertionError: False is not true : Got a valid type
Error output:
error: <user expression 1>:1:11: no known method '+stringWithCString:encoding:'; cast the message send to the method's return type
    1 | [NSString stringWithCString:"foo" encoding:1]
      | ~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Config=x86_64-/Users/michaelbuch/Git/lldb-build-main-no-modules/bin/clang
----------------------------------------------------------------------      ```

(cherry picked from commit 04b295e8938778251821f8a39903fdad0501112c)
JDevlieghere commented 2 weeks ago

@swift-ci test

adrian-prantl commented 2 weeks ago
C:\Users\swift-ci\jenkins\workspace\apple-llvm-project-pull-request-windows\swift-llvm-bindings failed (ret=1): ['git', 'checkout', 'swift/release/6.0']
b"error: pathspec 'swift/release/6.0' did not match any file(s) known to git\n"

@shahmishal Is this a bug in the bot config, or should this patch go to a different 6.x branch? (It's a backport for rdar://139654755)

JDevlieghere commented 1 week ago

@swift-ci test windows