Skip to content

Commit ab8e561

Browse files
authored
Merge pull request #78516 from al45tair/eng/PR-124913332
[Backtracing] Implement API per SE-0419
2 parents 248c026 + 26d0e49 commit ab8e561

File tree

107 files changed

+6179
-2406
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

107 files changed

+6179
-2406
lines changed

CMakeLists.txt

+6-9
Original file line numberDiff line numberDiff line change
@@ -695,10 +695,6 @@ option(SWIFT_IMPLICIT_CONCURRENCY_IMPORT
695695
"Implicitly import the Swift concurrency module"
696696
TRUE)
697697

698-
option(SWIFT_IMPLICIT_BACKTRACING_IMPORT
699-
"Implicitly import the Swift backtracing module"
700-
FALSE)
701-
702698
option(SWIFT_ENABLE_EXPERIMENTAL_CONCURRENCY
703699
"Enable build of the Swift concurrency module"
704700
FALSE)
@@ -731,6 +727,10 @@ option(SWIFT_ENABLE_SYNCHRONIZATION
731727
"Enable build of the Swift Synchronization module"
732728
FALSE)
733729

730+
option(SWIFT_ENABLE_RUNTIME_MODULE
731+
"Build the Swift Runtime module"
732+
FALSE)
733+
734734
option(SWIFT_ENABLE_VOLATILE
735735
"Enable build of the Swift Volatile module"
736736
FALSE)
@@ -865,11 +865,6 @@ if (CMAKE_Swift_COMPILER)
865865
SWIFT_SUPPORTS_DISABLE_IMPLICIT_STRING_PROCESSING_MODULE_IMPORT)
866866
message(STATUS " Implicit 'string-processing' import: ${SWIFT_SUPPORTS_DISABLE_IMPLICIT_STRING_PROCESSING_MODULE_IMPORT}")
867867

868-
# Same for _Backtracing.
869-
swift_supports_implicit_module("backtracing"
870-
SWIFT_SUPPORTS_DISABLE_IMPLICIT_BACKTRACING_MODULE_IMPORT)
871-
message(STATUS " Implicit 'backtracing' import: ${SWIFT_SUPPORTS_DISABLE_IMPLICIT_BACKTRACING_MODULE_IMPORT}")
872-
873868
swift_get_package_cmo_support(
874869
Swift_COMPILER_PACKAGE_CMO_SUPPORT)
875870
message(STATUS " Package CMO: ${Swift_COMPILER_PACKAGE_CMO_SUPPORT}")
@@ -1393,6 +1388,8 @@ if(SWIFT_BUILD_STDLIB OR SWIFT_BUILD_SDK_OVERLAY)
13931388
message(STATUS "Observation Support: ${SWIFT_ENABLE_EXPERIMENTAL_OBSERVATION}")
13941389
message(STATUS "Synchronization Support: ${SWIFT_ENABLE_SYNCHRONIZATION}")
13951390
message(STATUS "Volatile Support: ${SWIFT_ENABLE_VOLATILE}")
1391+
message(STATUS "Pointer Bounds Support: ${SWIFT_ENABLE_EXPERIMENTAL_POINTER_BOUNDS}")
1392+
message(STATUS "Runtime Support: ${SWIFT_ENABLE_RUNTIME_MODULE}")
13961393
message(STATUS "")
13971394
else()
13981395
message(STATUS "Not building Swift standard library, SDK overlays, and runtime")

Runtimes/Core/CMakeLists.txt

-1
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,6 @@ add_compile_options(
173173
"$<$<COMPILE_LANGUAGE:Swift>:SHELL:-Xfrontend -enable-experimental-concise-pound-file>"
174174
"$<$<COMPILE_LANGUAGE:Swift>:SHELL:-Xfrontend -enable-lexical-lifetimes=false>"
175175
"$<$<COMPILE_LANGUAGE:Swift>:SHELL:-Xfrontend -disable-implicit-concurrency-module-import>"
176-
"$<$<COMPILE_LANGUAGE:Swift>:SHELL:-Xfrontend -disable-implicit-backtracing-module-import>"
177176
"$<$<COMPILE_LANGUAGE:Swift>:SHELL:-Xfrontend -disable-implicit-string-processing-module-import>"
178177
"$<$<COMPILE_LANGUAGE:Swift>:SHELL:-Xfrontend -enforce-exclusivity=unchecked>"
179178
"$<$<COMPILE_LANGUAGE:Swift>:SHELL:-Xfrontend -enable-ossa-modules>"

cmake/modules/AddPureSwift.cmake

+1-7
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,7 @@ function(_add_host_swift_compile_options name)
2828
"$<$<COMPILE_LANGUAGE:Swift>:SHELL:-Xfrontend -disable-implicit-string-processing-module-import>")
2929
endif()
3030

31-
# Same for backtracing
32-
if (SWIFT_SUPPORTS_DISABLE_IMPLICIT_BACKTRACING_MODULE_IMPORT)
33-
target_compile_options(${name} PRIVATE
34-
"$<$<COMPILE_LANGUAGE:Swift>:SHELL:-Xfrontend -disable-implicit-backtracing-module-import>")
35-
endif()
36-
37-
if(SWIFT_ANALYZE_CODE_COVERAGE)
31+
if(SWIFT_ANALYZE_CODE_COVERAGE)
3832
set(_cov_flags $<$<COMPILE_LANGUAGE:Swift>:-profile-generate -profile-coverage-mapping>)
3933
target_compile_options(${name} PRIVATE ${_cov_flags})
4034
target_link_options(${name} PRIVATE ${_cov_flags})

docs/Backtracing.rst

+11
Original file line numberDiff line numberDiff line change
@@ -319,3 +319,14 @@ of the backtracer using
319319

320320
If the runtime is unable to locate the backtracer, it will allow your program to
321321
crash as it would have done anyway.
322+
323+
Backtrace Storage
324+
-----------------
325+
326+
Backtraces are stored internally in a format called :download:`Compact Backtrace
327+
Format <CompactBacktraceFormat.md>`. This provides us with a way to store a
328+
large number of frames in a much smaller space than would otherwise be possible.
329+
330+
Similarly, where we need to store address to image mappings, we
331+
use :download:`Compact ImageMap Format <CompactImageMapFormat.md>` to minimise
332+
storage requirements.

docs/CompactBacktraceFormat.md

+167
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
Compact Backtrace Format
2+
========================
3+
4+
We would like to be able to efficiently store and access backtraces,
5+
but we also wish to minimise the memory used to store them. Since
6+
backtraces typically contain a good deal of redundancy, it should be
7+
possible to compress the data.
8+
9+
Compact Backtrace Format (CBF) is a binary format for holding a
10+
backtrace; this specification addresses only the storage of the actual
11+
stack backtrace, and it does not consider storage of ancillary data
12+
(register contents, image lists and so on). Those will be dealt with
13+
separately elsewhere.
14+
15+
## General Format
16+
17+
Compact Backtrace Format data is byte aligned and starts with an
18+
information byte:
19+
20+
~~~
21+
7 6 5 4 3 2 1 0
22+
┌───────────────────────┬───────┐
23+
│ version │ size │
24+
└───────────────────────┴───────┘
25+
~~~
26+
27+
The `version` field identifies the version of CBF that is in use; this
28+
document describes version `0`. The `size` field is encqoded as
29+
follows:
30+
31+
| `size` | Machine word size |
32+
| :----: | :---------------- |
33+
| 00 | 16-bit |
34+
| 01 | 32-bit |
35+
| 10 | 64-bit |
36+
| 11 | Reserved |
37+
38+
This is followed by a series of instructions that tell the reader how
39+
to decode subsequent data.
40+
41+
The first instruction that computes an address _must_ specify an
42+
absolute address (the `a` bit must be set).
43+
44+
## Instructions
45+
46+
The following instructions are currently defined
47+
48+
| `opcode` | Mnemonic | Meaning |
49+
| :--------: | :------- | :---------------------------------------- |
50+
| `00000000` | `end` | Marks the end of the backtrace |
51+
| `00000001` | `trunc` | As above, but the backtrace was truncated |
52+
| `0000xxxx` | reserved | Reserved for future expansion |
53+
| `0001axxx` | `pc` | A program counter value follows |
54+
| `0010axxx` | `ra` | A return address value follows |
55+
| `0011axxx` | `async` | An async resume point follows |
56+
| `01xxxxxx` | `omit` | Indicates frames have been omitted |
57+
| `1000xxxx` | `rep` | Repeat the previous frame |
58+
| `1xxxxxxx` | reserved | Reserved for future expansion |
59+
60+
If the bit labelled `a` is set, it means that the address computation
61+
is absolute rather than being relative to the previously computed
62+
address.
63+
64+
### `end`/`trunc`
65+
66+
#### Encoding
67+
68+
~~~
69+
7 6 5 4 3 2 1 0
70+
┌───────────────────────────┬───┐
71+
│ 0 0 0 0 0 0 0 │ t │ end (or trunc if t is 1)
72+
└───────────────────────────┴───┘
73+
~~~
74+
75+
#### Meaning
76+
77+
Marks the end of the backtrace data. If `t` is set, it indicates that
78+
the backtrace was truncated at this point (for instance because we hit
79+
a frame limit while capturing).
80+
81+
It is not strictly necessary to use the `end` instruction if the
82+
CBF data is of a known length.
83+
84+
### `pc`, `ra`, `async`
85+
86+
#### Encoding
87+
88+
~~~
89+
7 6 5 4 3 2 1 0
90+
┌────────────────┬───┬──────────┐
91+
│ 0 0 0 1 │ a │ count │ pc
92+
└────────────────┴───┴──────────┘
93+
┌────────────────┬───┬──────────┐
94+
│ 0 0 1 0 │ a │ count │ ra
95+
└────────────────┴───┴──────────┘
96+
┌────────────────┬───┬──────────┐
97+
│ 0 0 1 1 │ a │ count │ async
98+
└────────────────┴───┴──────────┘
99+
~~~
100+
101+
#### Meaning
102+
103+
Each of these instructions represents a frame on the stack. For `pc`
104+
frames, the computed address is an actual program counter (aka
105+
instruction pointer) value. `ra` instructions instead represent a
106+
_return address_, the difference being that the program has not yet
107+
executed that instruction. `async` instructions point at the entry
108+
point of an async resume function, and are used when walking stacks on
109+
systems that support `async`/`await` primitives that are implemented
110+
by function splitting (typically an `async` instruction will point at
111+
the start of a function containing the code immediately following an
112+
`await`).
113+
114+
The next `count + 1` bytes following the instruction are an address
115+
value. If `a` is set, the computed address is equal to the address
116+
value. If `a` is not set, the computed address is equal to the
117+
preceding computed address *plus* the address value.
118+
119+
Address values are sign-extended to the machine word width before
120+
processing. Thus a single address byte with value `0xff` on a 32-bit
121+
backtrace represents the address value `0xffffffff`.
122+
123+
### `omit`
124+
125+
#### Encoding
126+
127+
~~~
128+
7 6 5 4 3 2 1 0
129+
┌───────┬───┬───────────────────┐
130+
│ 0 1 │ x │ count │ omit
131+
└───────┴───┴───────────────────┘
132+
~~~
133+
134+
#### Meaning
135+
136+
Indicates that a number of frames were skipped when capturing the
137+
backtrace. This is used to allow a backtrace to include both the top
138+
and bottom of the stack, without carrying every intervening frame, and
139+
is useful to prevent the data from exploding where recursion has taken
140+
place.
141+
142+
If `x` is `1`, the instruction is followed by `count + 1` bytes (up to the
143+
machine word length) that are zero-extended to machine word length and
144+
that represent a count of the number of frames that were omitted.
145+
146+
If `x` is `0`, `count + 1` is the number of frames that were omitted.
147+
148+
### `rep`
149+
150+
#### Encoding
151+
152+
~~~
153+
7 6 5 4 3 2 1 0
154+
┌────────────────┬───┬──────────┐
155+
│ 1 0 0 0 │ x │ count │ repeat
156+
└────────────────┴───┴──────────┘
157+
~~~
158+
159+
#### Meaning
160+
161+
Repeat the previous frame.
162+
163+
If `x` is `1`, the instruction is followed by `count + 1` bytes that are zero
164+
extended to machine word length and that represent a count of the number of
165+
times to repeat the preceding frame.
166+
167+
If `x` is `0`, the previous frame should be repeated `count + 1` times.

0 commit comments

Comments
 (0)