blob: 2df17727ef858b06e7fcda5ae1a8702d11c001b6 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
|
# preload-libbt
`preload-libbt` is a utility library for some very special occasions.
It aims to extract a backtrace when a program *segfaults*, on machines where
[`ptrace(2)`][ptrace] syscalls are restricted, and hence launching the program
under *gdb* or attaching wth *gdb* is not possible.
The library must be `LD_PRELOAD`ed, which then installs a signal handler that
dumps a stacktrace. For it to work the program must adhere to the following
rules:
- The program must not override the installed signal handler.
- If the program overrides the signal handler, it needs to implement chaining
signal handlers properly.
The preload library `libbt.so` is build with the default make target.
```
> make
cc -o libbt.so bt.c -shared -fPIC -static-libgcc -ldl -Wall -Wextra -g
```
## Concept
The library is based on the following features.
- Global signal disposition for `SIGSEGV`.
- *Alternate* signal stacks.
The signal handler for `SIGSEGV` is directly executed in the thread generating
the *segfault*. This is fine as long as the segfault is generated from anything
other than a *stackoverflow*. To also support this case, the library installs
an *alternate* signal stack with [`sigaltstack(2)`][sigaltstack] for each
thread by wrapping the [`pthread_create(3)`][pthread_create] call.
Support for threads created with raw [`clone(2)`][clone] calls is not
supported.
The examples `recurse1.c` and `recurse2.c` demonstrate the handling for
stackoverflows.
## Examples
The following gives an example and shows how a stacktrace dump looks like.
```
cc -o libbt.so bt.c -shared -fPIC -ldl
cc -o raise1 example/raise1.c -rdynamic
LD_PRELOAD=./libbt.so ./raise1
[BT:INFO]: installed signal handler
[BT:INFO]: caught signal 11
# 0 [ 0x7f53b9e203f4] /usr/lib/libc.so.6+0x963f4
# 1 [ 0x7f53b9dc7120] gsignal+0x20 /usr/lib/libc.so.6+0x3d100
# 2 [ 0x55748166c147] foo+0xe raise1+0x1139
# 3 [ 0x55748166c158] bar+0xe raise1+0x114a
# 4 [ 0x55748166c169] qux+0xe raise1+0x115b
# 5 [ 0x55748166c17a] main+0xe raise1+0x116c
# 6 [ 0x7f53b9dafe08] /usr/lib/libc.so.6+0x25e08
# 7 [ 0x7f53b9dafecc] __libc_start_main+0x8c /usr/lib/libc.so.6+0x25e40
# 8 [ 0x55748166c065] _start+0x25 raise1+0x1040
```
Alternatively one can run `make run`, to run all examples under `example/`.
## License
This project is licensed under the MIT license.
[clone]: https://www.man7.org/linux/man-pages/man2/clone.2.html
[ptrace]: https://www.man7.org/linux/man-pages/man2/ptrace.2.html
[sigaltstack]: https://www.man7.org/linux/man-pages/man2/sigaltstack.2.html
[pthread_create]: https://www.man7.org/linux/man-pages/man3/pthread_create.3.html
|