[Debugging] Add lldb data formatter for RigidArray#607
[Debugging] Add lldb data formatter for RigidArray#607kastiglione wants to merge 13 commits intoapple:mainfrom
Conversation
This introduces a debugging data formatter for RigidArray using a new feature of LLDB: [Formatter Bytecode][1]. The scope of this PR is a single initial data type, with the short and long term plan being to support all types vended by Swift Collections. The bytecode for this implementation is produced using a Python -> Formatter Bytecode compiler, contained in the [`formatter_bytecode`][2] module. The workflow for authoring and shipping the formatter is: 1. Update RigidArray.py as needed 2. Compile RigidArray.py to RigidArray+Formatter.swift (again, `formatter_bytecode`) 3. Compile RigidArray+Formatter.swift as part of the BasicContainers module By including the bytecode in the binary, lldb can load RigidArray's data formatter automatically, without any friction that comes with installation, setup, config, updating, or versioning. [1]: https://lldb.llvm.org/resources/formatterbytecode.html [2]: https://github.com/llvm/llvm-project/blob/main/lldb/examples/python/formatter_bytecode.py
|
Draft mode until completion of the following:
To manage the scope of this first PR, I'm leaving the following desirable features for future followups:
|
| @@ -0,0 +1,38 @@ | |||
| #if swift(>=6.3) | |||
There was a problem hiding this comment.
What do you think about adding either a comment at the top of this file with instructions for how to regenerate it from the python source?
I guess that could even be a feature of the compiler script...
There was a problem hiding this comment.
A comment is now added as part of the new generate_formatters.sh script.
| #if os(macOS) || os(iOS) || os(watchOS) || os(tvOS) || os(visionOS) | ||
| @section("__DATA_CONST,__lldbformatters") | ||
| #else | ||
| @section(".lldbformatters") | ||
| #endif |
There was a problem hiding this comment.
Should this be using:
-
#if objectFormat(…)from SE-0492 — with section names forMachO,ELF,COFF, andWasm? -
#if os(anyAppleOS)when using a Swift 6.4 compiler?
There was a problem hiding this comment.
TIL I learned about these. Thank you. I will update it accordingly.
| @used | ||
| let __BasicContainers___RigidArray______formatter: (UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8) = ( |
There was a problem hiding this comment.
Could this use a raw identifier from SE-0451, instead of the replacement underscores?
I was also going to ask about using an InlineArray literal, but then I found your previous discussion.
There was a problem hiding this comment.
I will look into whether it would be feasible to allow InlineArray to be used in the future as a constant.
There was a problem hiding this comment.
A raw identifier is another good suggestion. The name of this is irrelevant to lldb.
Following feedback from @benrimmington in apple/swift-collections#607, this changes the following: 1. Uses `objectFormat()` compiler conditional instead of `os()` (see "Cross-platform object file format support" in [SE-0492](https://github.com/swiftlang/swift-evolution/blob/main/proposals/0492-section-control.md#cross-platform-object-file-format-support)) 2. Uses a raw identifier for the generated Swift symbol name, instead of an escaped name (see [SE-0451](https://github.com/swiftlang/swift-evolution/blob/main/proposals/0451-escaped-identifiers.md))
…(#189425) Following feedback from @benrimmington in apple/swift-collections#607, this changes the following: 1. Uses `objectFormat()` compiler conditional instead of `os()` (see "Cross-platform object file format support" in [SE-0492](https://github.com/swiftlang/swift-evolution/blob/main/proposals/0492-section-control.md#cross-platform-object-file-format-support)) 2. Uses a raw identifier for the generated Swift symbol name, instead of an escaped name (see [SE-0451](https://github.com/swiftlang/swift-evolution/blob/main/proposals/0451-escaped-identifiers.md))
Utils/Debugger/HEADER.swift
Outdated
| // | ||
| // This source file is part of the Swift Collections open source project | ||
| // | ||
| // Copyright (c) 2024 - 2026 Apple Inc. and the Swift project authors |
There was a problem hiding this comment.
| // Copyright (c) 2024 - 2026 Apple Inc. and the Swift project authors | |
| // Copyright (c) 2026 Apple Inc. and the Swift project authors |
| @section(".lldbformatters") | ||
| #endif | ||
| @used | ||
| let `^BasicContainers[.]RigidArray<.+>$ formatter`: (UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8) = ( |
There was a problem hiding this comment.
This will fail to work in single-module mode (COLLECTIONS_SINGLE_MODULE), where the sources are combined into a single module. (The Xcode project inside Xcode is a good way to exercise that. The module name in that configuration is Collections in this repo, but we edit that when we build for adopters inside Apple OSes.)
We could surround the template with #if !COLLECTIONS_SINGLE_MODULE, but that would make debugging code less pleasant for OS engineers, so the right move is probably to duplicate this:
#if COLLECTIONS_SINGLE_MODULE
...
let `^BasicContainers[.]RigidArray<.+>$ formatter`: ... = ...
#else
...
let `^Collections[.]RigidArray<.+>$ formatter`: ... = ...
#endif
That's yucky, but it works. (I don't think we can do #if conditions just around the symbol name... 😞
There was a problem hiding this comment.
We could put the set of known module names into the regex:
^(BasicContainers|Collections)[.]RigidArray<.+>$
We've discussed having the module name be implicit, but I don't yet know if that's doable in practice.
There was a problem hiding this comment.
That's a much better solution! 👍
| ## | ||
| ## This source file is part of the Swift Collections open source project | ||
| ## | ||
| ## Copyright (c) YEARS Apple Inc. and the Swift project authors |
There was a problem hiding this comment.
| ## Copyright (c) YEARS Apple Inc. and the Swift project authors | |
| ## Copyright (c) 2026 Apple Inc. and the Swift project authors |
| curl -fsSL \ | ||
| "https://raw.githubusercontent.com/llvm/llvm-project/$COMPILER_VERSION/lldb/examples/python/formatter_bytecode.py" \ | ||
| -o "$compiler" |
There was a problem hiding this comment.
I have reservations about downloading scripts sight unseen for execution on engineers' machines. Can we just copy the formatter directly into this repo, like we used to do with gyb?
When `COLLECTIONS_SINGLE_MODULE` is set, a single `Collections` module is built. Type names need to match accordingly.
Following feedback from @benrimmington in apple/swift-collections#607, this changes the following: 1. Uses `objectFormat()` compiler conditional instead of `os()` (see "Cross-platform object file format support" in [SE-0492](https://github.com/swiftlang/swift-evolution/blob/main/proposals/0492-section-control.md#cross-platform-object-file-format-support)) 2. Uses a raw identifier for the generated Swift symbol name, instead of an escaped name (see [SE-0451](https://github.com/swiftlang/swift-evolution/blob/main/proposals/0451-escaped-identifiers.md)) (cherry picked from commit b66d98a)
This introduces a debugging data formatter for RigidArray using a new feature of LLDB: Formatter Bytecode. The scope of this PR is a single initial data type, with the short and long term plan being to support all types vended by Swift Collections.
The bytecode for this implementation is produced using a Python -> Formatter Bytecode compiler, contained in the
formatter_bytecodemodule.The workflow for authoring and shipping the formatter is:
formatter_bytecode)By including the bytecode in the binary, lldb can load RigidArray's data formatter automatically, without any friction that comes with installation, setup, config, updating, or versioning.