Skip to content

Commit fbbb560

Browse files
committed
docs: convert Backtracing.rst to Markdown
Resolves partially #49997.
1 parent 4e14288 commit fbbb560

File tree

2 files changed

+166
-227
lines changed

2 files changed

+166
-227
lines changed

docs/Backtracing.md

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
# Backtracing support in Swift
2+
3+
When things go wrong, it's always useful to be able to get a backtrace
4+
showing where the problem occurred in your program.
5+
6+
Broadly speaking there are three circumstances where you might want a
7+
backtrace, namely:
8+
9+
- Program crashes
10+
- Runtime errors
11+
- Specific user-defined program events
12+
13+
Historically, Swift has tended to lean on operating system crash
14+
catching support for the first two of these, and hasn't really provided
15+
any built-in support for the latter. This is fine for Darwin, where the
16+
operating system provides a comprehensive system-wide crash catching
17+
facility; it's just about OK on Windows, which also has system-wide
18+
crash logging; but it isn't great elsewhere, in particular on Linux
19+
where a lot of server-side Swift programs currently rely on a separate
20+
package to provide them with some level of backtrace support when errors
21+
happen.
22+
23+
## What does Swift now support?
24+
25+
Swift now supports:
26+
27+
- Automatic crash catching and backtrace generation out of the box.
28+
- Built-in symbolication.
29+
- A choice of unwind algorithms, including "fast", DWARF and SEH.
30+
- Interactive(!) crash/runtime error catching.
31+
32+
Crash catching is enabled by default, and won't interfere with any
33+
system-wide crash reporters you might be using.
34+
35+
## How do I configure backtracing?
36+
37+
There is an environment variable, `SWIFT_BACKTRACE`, that can be used to
38+
configure Swift's crash catching and backtracing support. The variable
39+
should contain a `,`-separated list of `key=value` pairs. Supported keys
40+
are as follows:
41+
42+
| Key | Default | Meaning |
43+
| ---------------- | -------- | -------------------------------------------------------------------------------------- |
44+
| enable | yes[^*] | Set to `no` to disable crash catching, or `tty` to enable only if stdin is a terminal. |
45+
| demangle | yes | Set to `no` to disable demangling. |
46+
| interactive | tty | Set to `no` to disable interaction, or `yes` to enable always. |
47+
| color | tty | Set to `yes` to enable always, or `no` to disable. Uses ANSI escape sequences. |
48+
| timeout | 30s | Time to wait for interaction when a crash occurs. Setting this to `none` or `0s` will disable interaction. |
49+
| unwind | auto | Specifies which unwind algorithm to use. `auto` means to choose appropriately for the platform. Other options are `fast`, which does a naïve stack walk; and `precise`, which uses exception handling data to perform an unwind. |
50+
| preset | auto | Specifies which set of preset formatting options to use. Options are `friendly`, `medium` or `full`. `auto` means to use `friendly` if interactive, and `full` otherwise. |
51+
| sanitize | preset | If `yes`, we will try to process paths to remove PII. Exact behaviour is platform dependent. |
52+
| threads | preset | Options are `all` to show backtraces for every thread, or `crashed` to show only the crashing thread. |
53+
| registers | preset | Options are `none`, `all` or `crashed`. |
54+
| images | preset | Options are `none`, `all`, or `mentioned`, which only displays images mentioned in a backtrace.
55+
| limit | 64 | Limits the length of the captured backtrace. See below for a discussion of its behaviour. Can be set to `none` to mean no limit. |
56+
| top | 16 | Specify a minimum number of frames to capture from the top of the stack. See below for more. |
57+
| cache | yes | Set to `no` to disable symbol caching. This only has effect on platforms that have a symbol cache that can be controlled by the runtime. |
58+
| swift-backtrace | | If specified, gives the full path to the swift-backtrace binary to use for crashes. Otherwise, Swift will locate the binary relative to the runtime library, or using `SWIFT_ROOT`. |
59+
60+
[^*]: On macOS, this defaults to `tty` rather than `yes`.
61+
62+
## Backtrace limits
63+
64+
The limit settings are provided both to prevent runaway backtraces and
65+
to allow for a sensible backtrace to be produced even when a function
66+
has blown the stack through excessive recursion.
67+
68+
Typically in the latter case you want to capture some frames at the top
69+
of the stack so that you can see how the recursion was entered, and the
70+
frames at the bottom of the stack where the actual fault occurred.
71+
72+
1. There are `limit` or fewer frames. In this case we will display all
73+
the frames in the backtrace. Note that this \_[includes]() the case
74+
where there are exactly `limit` frames.
75+
2. There are more than `limit` frames.
76+
1. `top` is `0`. We will display the first `limit - 1` frames
77+
followed by `...` to indicate that more frames exist.
78+
2. `top` is less than `limit - 1`. We will display
79+
`limit - 1 - top` frames from the bottom of the stack, then a
80+
`...`, then `top` frames from the top of the stack.
81+
3. `top` is greater or equal to `limit - 1`. We will display `...`,
82+
followed by `limit - 1` frames from the top of the stack.
83+
84+
For example, let's say we have a stack containing 10 frames numbered
85+
here 1 to 10, with 10 being the innermost frame. With `limit` set to 5,
86+
you would see:
87+
88+
10
89+
9
90+
8
91+
7
92+
...
93+
94+
With `limit` set to 5 and `top` to 2, you would instead see:
95+
96+
10
97+
9
98+
...
99+
2
100+
1
101+
102+
And with `limit` set to 5 and `top` to 4 or above, you would see:
103+
104+
...
105+
4
106+
3
107+
2
108+
1
109+
110+
## What is the swift-backtrace binary?
111+
112+
`swift-backtrace` is a program that gets invoked when your program
113+
crashes. We do this because when a program crashes, it is potentially in
114+
an invalid state and there is very little that is safe for us to do. By
115+
executing an external helper program, we ensure that we do not interfere
116+
with the way the program was going to crash (so that system-wide crash
117+
catchers will still generate the correct information), and we are also
118+
able to use any functionality we need to generate a decent backtrace,
119+
including symbolication (which might in general require memory
120+
allocation, fetching and reading remote files and so on).
121+
122+
You shouldn't try to run `swift-backtrace` yourself; it has unusual
123+
requirements, which vary from platform to platform. Instead, it will be
124+
triggered automatically by the runtime.
125+
126+
## System specifics
127+
128+
### macOS
129+
130+
On macOS, we catch crashes and other events using a signal handler. At
131+
time of writing, this is installed for the following signals:
132+
133+
| Signal || Description | Comment |
134+
|---------|---------|---------------------------|------------------------------------------------------|
135+
| 3 | SIGQUIT | Quit program | |
136+
| 4 | SIGILL | Illegal instruction | |
137+
| 5 | SIGTRAP | Trace trap | |
138+
| 6 | SIGABRT | Abort program | |
139+
| 8 | SIGFPE | Floating point exception | On Intel, integer divide by zero also triggers this. |
140+
| 10 | SIGBUS | Bus error | |
141+
| 11 | SIGSEGV | Segmentation violation | |
142+
143+
If crash catching is enabled, the signal handler will be installed for
144+
any process that links the Swift runtime. If you replace the handlers
145+
for any of these signals, your program will no longer produce backtraces
146+
for program failures that lead to the handler you have replaced.
147+
148+
Additionally, the runtime will configure an alternate signal handling
149+
stack, so that stack overflows can be successfully trapped.
150+
151+
Note that the runtime will not install its signal handlers for a signal
152+
if it finds that there is already a handler for that signal. Similarly
153+
if something else has already configured an alternate signal stack, it
154+
will leave that stack alone.
155+
156+
Once the backtracer has finished handling the crash, it will allow the
157+
crashing program to continue and crash normally, which will result in
158+
the usual Crash Reporter log file being generated.
159+
160+
Crash catching *cannot* be enabled for setuid binaries. This is
161+
intentional as doing so might create a security hole.
162+
163+
### Other Darwin (iOS, tvOS)
164+
165+
Crash catching is not enabled for non-macOS Darwin. You should continue
166+
to look at the system-provided crash logs.

0 commit comments

Comments
 (0)