116 lines
3.9 KiB
Markdown
116 lines
3.9 KiB
Markdown
# All the backtrace, none of the overhead
|
|
|
|
[![Build Status](https://travis-ci.org/status-im/nim-libbacktrace.svg?branch=master)](https://travis-ci.org/status-im/nim-libbacktrace)
|
|
[![Build status](https://ci.appveyor.com/api/projects/status/mrvu6ks50dl5y5y4/branch/master?svg=true)](https://ci.appveyor.com/project/nimbus/nim-libbacktrace/branch/master)
|
|
[![License: Apache](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
|
|
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
|
|
![Stability: experimental](https://img.shields.io/badge/stability-experimental-orange.svg)
|
|
|
|
Nim's default stack tracing functionality comes with significant
|
|
overhead, by adding `nimln_()`, `nimfr_()` calls all over the place. The
|
|
problem is being discussed upstream in [this GitHub
|
|
issue](https://github.com/nim-lang/Nim/issues/12702).
|
|
|
|
That `popFrame()` at the end of each C function is particularly problematic,
|
|
since it prevents the C compiler from doing tail-call optimisations.
|
|
|
|
This is a lightweight alternative based on libbacktrace, meant to offer the
|
|
same stack traces without the runtime overhead.
|
|
|
|
C++ function name demangling is supported using "\_\_cxa\_demangle()".
|
|
|
|
## Building & Testing
|
|
|
|
This project uses Git submodules, so get it with:
|
|
|
|
```bash
|
|
git clone https://github.com/status-im/nim-libbacktrace.git
|
|
cd nim-libbacktrace
|
|
git submodule update --init
|
|
```
|
|
|
|
You build the library (or libraries, on macOS) with `make`. You test it with
|
|
`make test`.
|
|
|
|
Nimble is grudgingly supported, so `nimble install` works. (No, we will not
|
|
let a silly package manager dictate our project's structure. People have the
|
|
power!)
|
|
|
|
## Supported platforms
|
|
|
|
Tested with GCC and LLVM on Linux, macOS and 64-bit Windows (with Mingw-w64 and
|
|
the MSYS that comes with "Git for Windows").
|
|
|
|
## Usage
|
|
|
|
bttest.nim:
|
|
|
|
```nim
|
|
import libbacktrace
|
|
|
|
# presumably in some procedure:
|
|
echo getBacktrace()
|
|
|
|
# Should be the same output as writeStackTrace() - minus the header.
|
|
# When the C compiler inlines some procs, libbacktrace might get confused with proc names,
|
|
# but it gets the files and line numbers right nonetheless.
|
|
```
|
|
|
|
We need debugging symbols in the binary and we can do without Nim's bloated and
|
|
slow stack trace implementation:
|
|
|
|
```bash
|
|
nim c -f --debugger:native --stacktrace:off bttest.nim
|
|
```
|
|
|
|
If you're unfortunate enough to need this on macOS, [there's an extra
|
|
step](https://github.com/nim-lang/Nim/issues/12735) for creating debugging
|
|
symbols:
|
|
|
|
```bash
|
|
dsymutil bttest
|
|
```
|
|
|
|
Now you can run it:
|
|
|
|
```bash
|
|
./bttest
|
|
```
|
|
|
|
### Debugging
|
|
|
|
`export NIM_LIBBACKTRACE_DEBUG=1` to see the trace lines hidden by default.
|
|
|
|
## Dependencies
|
|
|
|
You need Make, CMake and, of course, Nim up and running.
|
|
|
|
The other dependencies are bundled, for your convenience. We use a [libbacktrace
|
|
fork](https://github.com/rust-lang-nursery/libbacktrace/tree/rust-snapshot-2018-05-22)
|
|
with macOS support and [LLVM's libunwind
|
|
variant](https://github.com/llvm-mirror/libunwind) that's needed on macOS and Windows.
|
|
|
|
If you know better and want to use your system's libbacktrace package instead
|
|
of the bundled one, you can, with `make USE_SYSTEM_LIBS=1` and by passing
|
|
`-d:libbacktraceUseSystemLibs` to the Nim compiler.
|
|
|
|
How does libbacktrace work on systems without libunwind installed, I hear you
|
|
asking? It uses GCC's basic unwind support in libgcc\_s.so.1 - that runtime's so
|
|
good that even Clang links it by default ;-)
|
|
|
|
To get the running binary's path in a cross-platform way, we rely on
|
|
[whereami](https://github.com/gpakosz/whereami).
|
|
|
|
## License
|
|
|
|
Licensed and distributed under either of
|
|
|
|
* MIT license: [LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT
|
|
|
|
or
|
|
|
|
* Apache License, Version 2.0, ([LICENSE-APACHEv2](LICENSE-APACHEv2) or http://www.apache.org/licenses/LICENSE-2.0)
|
|
|
|
at your option. These files may not be copied, modified, or distributed except according to those terms.
|
|
|