Skip to content

Commit 24932f2

Browse files
committed
[Backtracing][Docs] Add an explanation of the workings of the backtracer.
Add some discussion of how the new external backtracer works and what options are available. rdar://105394365
1 parent dc6f97c commit 24932f2

File tree

2 files changed

+172
-0
lines changed

2 files changed

+172
-0
lines changed

docs/Backtracing.rst

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

docs/README.md

+3
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,9 @@ documentation, please create a thread on the Swift forums under the
136136
operations on [currency](/docs/Lexicon.md#currency-type) data types and
137137
optimizes accordingly.
138138
Includes a thorough discussion of the `@_semantics` attribute.
139+
- Runtime specifics:
140+
- [Backtracing.rst](/docs/Backtracing.rst):
141+
Describes Swift's backtracing and crash catching support.
139142

140143
### SourceKit subsystems
141144

0 commit comments

Comments
 (0)