Skip to content

Commit 3bd764d

Browse files
authored
Merge pull request #69897 from ahoppen/ahoppen/doc-lsan-ci-failures
[Docs] Add documentation how to diagnose LSAN CI failures
2 parents 1296aee + bbb06a7 commit 3bd764d

File tree

1 file changed

+78
-0
lines changed

1 file changed

+78
-0
lines changed

docs/LSANFailureSymbolication.md

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
# Diagnose LSAN Failures in the Compiler
2+
3+
### Create Ubuntu Container
4+
5+
1. Clone (or pull) swift-docker: https://github.com/apple/swift-docker
6+
2. Build the Ubuntu 18.04 container: `cd swift-ci/master/ubuntu/18.04; docker build .`
7+
3. `docker run -it —cpus <CPUs> —memory <Memory> -v ~/<path to your local sources>:/src-on-host:cached —name lsan-reproducer —cap-add=SYS_PTRACE —security-opt seccomp=unconfined <hash that docker build outputs> bash`
8+
- The `-cap-add` and `-security-opt` arguments are needed to run LLDB inside the Docker container
9+
4. Copy the sources to inside the Docker container: `cp /src-on-host/* ~`
10+
- We need to to this because the build needs a case-sensitive file system and your host machine probably has a case-insensitive file system
11+
12+
Build inside the Container
13+
14+
1. `utils/build-script --preset buildbot_incremental_linux,lsan,tools=RDA,stdlib=DA,test=no`
15+
2. This should reproduce the LSAN failure
16+
3. Now, disassemble the failing CMake invocation to a swiftc invocation. I needed to set one environment variable and could the copy the swiftc invocation (but this might change as the build changes)
17+
18+
```
19+
export LD_LIBRARY_PATH=/opt/swift/5.8.1/usr/lib/swift/linux
20+
/home/build-user/build/buildbot_incremental_lsan/swift-linux-x86_64/./bin/swiftc <many arguments>
21+
```
22+
23+
### Symbolicating the LSAN report
24+
25+
For reasons that are not clear to me, LSAN does not symbolicate the report. To get the functions at the reported offsets, perform the following steps (there might be easier steps, please update this document if you know any).
26+
27+
1. Run the swiftc invocation that fails and copy the leak report to somewhere. The leak report should look like the following.
28+
```
29+
==3863==ERROR: LeakSanitizer: detected memory leaks
30+
31+
Direct leak of 120 byte(s) in 3 object(s) allocated from:
32+
#0 0x55b91c0b59b8 (/home/build-user/build/buildbot_incremental_lsan/swift-linux-x86_64/bin/swift-frontend+0x14d09b8)
33+
#1 0x55b91d51281c (/home/build-user/build/buildbot_incremental_lsan/swift-linux-x86_64/bin/swift-frontend+0x292d81c)
34+
#2 0x55b91c1b8700 (/home/build-user/build/buildbot_incremental_lsan/swift-linux-x86_64/bin/swift-frontend+0x15d3700)
35+
36+
SUMMARY: LeakSanitizer: 120 byte(s) leaked in 3 allocation(s).
37+
```
38+
2. `lldb -- <your swiftc invocation above>`
39+
3. Set a breakpoint somewhere in swiftc, eg. at the start of main: `br s -f driver.cpp -l 19`. This should output something like
40+
41+
```
42+
Breakpoint 1: where = swiftc`main + 4 at driver.cpp:20:10, address = 0x00000000014d25d4
43+
```
44+
45+
4. Run swiftc to the breakpoint
46+
5. This should stop you with something like
47+
48+
```
49+
* thread #1, name = 'swiftc', stop reason = breakpoint 1.1
50+
frame #0: 0x0000555556a265d4 swiftc`main(argc_=168, argv_=0x00007fffffffced8) at driver.cpp:20:10
51+
17 #include "swift/DriverTool/DriverTool.h"
52+
18
53+
19 int main(int argc_, const char **argv_) {
54+
→ 20 return swift::mainEntry(argc_, argv_);
55+
21 }
56+
```
57+
58+
6. Find the loaded offset of swift-frontend by subtracting the breakpoint address from the frame address. With the example above, that’s `0x0000555556a265d4 - 0x00000000014d25d4 = 0x555555554000`.
59+
7. For the frame that you want to symbolicate,, add the offset you computed above to the stack frame in the LSAN report, eg. to symbolicate frame 1 `0x555555554000 + 0x292d81c = 0x555557E8181C`
60+
8. Look up the address using `image lookup -a <address you computed>`. This should output something like
61+
62+
```
63+
(lldb) image lookup -a 0x555557E8181C
64+
Address: swiftc[0x000000000292d81c] (swiftc.PT_LOAD[0]..text + 22056284)
65+
Summary: swiftc`registerFunctionTest(BridgedStringRef, void*) + 28 at SILBridging.cpp:148:3
66+
```
67+
68+
9. Hoorray, you know which function is leaking.
69+
70+
### Making Local Changes Inside the Container
71+
72+
For example, to install vim in the container run
73+
74+
```
75+
docker exec -u 0:0 -it lsan-reproducer bash
76+
$ apt update
77+
$ apt install vim
78+
```

0 commit comments

Comments
 (0)