Giter Site home page Giter Site logo

sentry-contrib-native's Introduction

Deprecated

This crate has been deprecated in favor of crash-handler, a pure Rust alternative to relying on Sentry's C/C++ SDK.

See sentry-rust-minidump as well for more integration with Sentry.

sentry-contrib-native

Crates.io Libraries.io Commits since License LoC

Release: Build Docs

Master: Build Docs

Table of contents

Description

Unofficial bindings to the Sentry Native SDK for Rust. See the Alternatives section for details on the official Sentry SDK for Rust.

This crates main purpose is to enable an application to send reports to Sentry even if it crashes, which is currently not covered by the official Sentry SDK for Rust.

Branches

  • release - For releases only.
  • master - For active development inluding PR's.

Usage

use sentry_contrib_native as sentry;
use sentry::{Event, Level, Options};
use std::ptr;

fn main() {
    // set up panic handler
    sentry::set_hook(None, None);
    // start Sentry
    let mut options = Options::new();
    options.set_dsn("your-sentry-dsn.com");
    let _shutdown = options.init().expect("failed to initialize Sentry");

    // send an event to Sentry
    Event::new_message(Level::Debug, None, "test");

    // this code triggers a crash, but it will still be reported to Sentry
    unsafe { *ptr::null_mut() = true; }

    // Sentry receives an event with an attached stacktrace and message
    panic!("application should have crashed at this point");
}

By default, on Linux, MacOS and Windows the Crashpad handler executable has to be shipped with the application, for convenience the Crashpad handler executable will be copied to Cargo's default binary output folder, so using cargo run works without any additional setup or configuration.

If you need to export the Crashpad handler executable programmatically to a specific output path, a "convenient" environment variable is provided to help with that: DEP_SENTRY_NATIVE_CRASHPAD_HANDLER.

Here is an example build.rs.

use std::{env, fs, path::Path};

static OUTPUT_PATH: &str = "your/output/path";

fn main() {
    let target_os = env::var_os("CARGO_CFG_TARGET_OS").unwrap();

    let handler = env::var_os("DEP_SENTRY_NATIVE_CRASHPAD_HANDLER").unwrap();
    let executable = if target_os == "windows" {
        "crashpad_handler.exe"
    } else {
        "crashpad_handler"
    };

    fs::copy(handler, Path::new(OUTPUT_PATH).join(executable)).unwrap();
}

If you are using panic = abort make sure to let the panic handler call shutdown to flush remaining transport before aborting the application.

use sentry_contrib_native as sentry;

std::panic::set_hook(Box::new(|_| sentry::shutdown()));
// or with the provided hook
sentry::set_hook(None, Some(Box::new(|_| sentry::shutdown())));

Platform support

Currently the following systems are tested with CI:

  • x86_64-unknown-linux-gnu
  • x86_64-apple-darwin
  • aarch64-apple-darwin (building only)
  • x86_64-pc-windows-msvc

See the CI itself for more detailed information. See the Sentry Native SDK for more platform and feature support details there, this crate doesn't do anything fancy, so we mostly rely on sentry-native for support.

The default backend for Linux is changed from Breakpad to Crashpad.

The default transport for Android is changed from none to Curl.

The default behaviour of including the system shared zlib is disabled and instead built from source.

Only the default backend is tested in the CI.

Build

This crate relies on sentry-contrib-native-sys which in turn builds Sentry's Native SDK. This requires CMake.

Alternatively a path to a pre-built version of Sentry's Native SDK can be provided with the SENTRY_NATIVE_INSTALL environment variable. If none is found at that path, sentry-contrib-native-sys will use that path as the build output.

Additionally, if the transport-default feature on Android, Linux and MacOS is used, the development version of Curl is required. For example on Ubuntu you can use the libcurl4-openssl-dev package.

See the Sentry Native SDK for more details.

Crate features

  • transport-default - Enabled by default, will use WinHttp on Windows and Curl everywhere else as the default transport.
  • backend-crashpad - Will use Crashpad.
  • backend-breakpad - Will use Breakpad.
  • backend-inproc - Will use InProc.
  • transport-custom - Adds helper types and methods to custom transport.

By default the selected backend will be Crashpad for Linux, MacOS and Windows and InProc for Android, even if no corresponding feature is active. See SENTRY_BACKEND for more information on backends.

Deployment

If the Crashpad backend is used, which is the default on Linux, MacOS or Windows, the application has to be shipped together with the crashpad_handler(.exe) executable. A way to programmatically export it using build.rs is provided through the DEP_SENTRY_NATIVE_CRASHPAD_HANDLER.

See the Usage section for an example.

Documentation

Tests

For correct testing the following has to be provided:

  • SENTRY_DSN environment variable has to contain a valid Sentry DSN URL.
  • SENTRY_TOKEN environment variable has to contain a valid Sentry API Token with read access to "Organization", "Project" and "Issue & Event".

Tests may easily exhaust large number of events and you may not want to expose a Sentry API token, therefore it is recommended to run tests against a Sentry onpremise server, it is quiet easy to set up.

The hidden cargo feature test is automatically activated when testing. It has the following effects:

  • Automatically sets the DSN to the SENTRY_DSN environment variable, no matter what is set through Options::set_dsn.
  • Automatically sets the database path to the OUT_DIR environment variable, no matter what is set through Options::set_database_path.
  • Automatically puts the crashpad handler path to the correct path, taking into account SENTRY_NATIVE_INSTALL, no matter what is set through Options::set_handler_path.

cargo test

Alternatives

It's recommended to use Sentry's official SDK for Rust: sentry - Crates.io.

The official SDK provides a much better user experience and customizability.

In comparison the only upside this crate can provide is application crash handling, the official SDK for Rust can only handle panics.

Changelog

See the CHANGELOG file for details.

License

Licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Attribution

Used documentation from Sentry Native SDK: MIT

See the ATTRIBUTION file for more details.

sentry-contrib-native's People

Contributors

daxpedda avatar dependabot[bot] avatar jake-shadle avatar jesdazrez avatar marijns95 avatar swatinem avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

sentry-contrib-native's Issues

Expose custom transports

We want to be able to provide our own transport functions from Rust so the we don't have to compile and link in undesirable libraries (eg OpenSSL) and can use whatever HTTP client we already use for the rest of our Rust code.

Just adding this issue to let you know I'm working on this today.

Crash report failure when using Options::set_before_send

Describe the bug
If Options::set_before_send is used, and a native crash occurs, sentry fails to serialize the envelope contain the minidump to disk, which means subsequent runs can't send the crash and it goes unreported.

To Reproduce

  1. Setup Sentry, including set_before send
let mut opts = sentry_native::Options::new();
opts.set_debug(config.verbose);

opts.set_before_send(|val: sentry_native::Value| {
    if let Some(event) = val.as_map() {
        if let Some(id) = event.get("event_id") {
            println!("sending sentry event {}", id.as_str().unwrap());
        }
    }

    val
});

let shutdown = opts.init()?;
  1. Force a crash
let s: &u32 = unsafe { &*std::ptr::null() };

println!("we are crashing by accessing a null reference: {}", *s);
  1. With debug output enabled for the SDK, you should see a line saying [sentry] DEBUG failed to open file "/<uuid>.envelope" for writing

Expected behavior
The envelope should be serialized to disk, and subsequent runs should send those envelopes to the upstream sentry server for consumption and analysis.

Environment:

  • OS: Fedora 32
  • Default transport both exhibit the same behavior
  • Version 5f4bf1f
  • Rust 1.44.1

Additional context
So after some digging, it appears as if some memory might be getting stomped during the before_send callback, I don't think it's in the native code as there doesn't seem to be much going on there, but I could of course be wrong. But basically, the options run field has the run_path which is the directory where sentry stores serialized envelopes and temporary crash dumps, but if the before_send callback is set and called, run_path ends up being an empty string, so when sentry creates the path to store the serialized envelope in by joining the run_path with the uuid + .envelope extension, which should be an absolute path, it ends up being just /<uuid>.envelope which then fails to be created and sentry gives up serializing the envelope and the crash is lost forever.

I would look into this more but once I realized that before_send was causing this I just stopped using it (it was only for logging purposes) so I could move on, but thought I would at least make this report so that there's a record of it. ๐Ÿ™‚

Build fails on macOS 12.3.1 (since python 2.7 is removed in that version)

Title says it all.

$ cargo b
   Compiling sentry-contrib-native-sys v0.3.1
error: failed to run custom build command for `sentry-contrib-native-sys v0.3.1`

Caused by:
  process didn't exit successfully: `/Users/alex/***/target/debug/build/sentry-contrib-native-sys-2c5dda3f75ccf618/build-script-build` (exit status: 101)
  --- stdout
  CMAKE_TOOLCHAIN_FILE_x86_64-apple-darwin = None
  CMAKE_TOOLCHAIN_FILE_x86_64_apple_darwin = None
  HOST_CMAKE_TOOLCHAIN_FILE = None
  CMAKE_TOOLCHAIN_FILE = None
  CMAKE_GENERATOR_x86_64-apple-darwin = None
  CMAKE_GENERATOR_x86_64_apple_darwin = None
  HOST_CMAKE_GENERATOR = None
  CMAKE_GENERATOR = None
  CMAKE_PREFIX_PATH_x86_64-apple-darwin = None
  CMAKE_PREFIX_PATH_x86_64_apple_darwin = None
  HOST_CMAKE_PREFIX_PATH = None
  CMAKE_PREFIX_PATH = None
  CMAKE_x86_64-apple-darwin = None
  CMAKE_x86_64_apple_darwin = None
  HOST_CMAKE = None
  CMAKE = None
  running: "cmake" "/Users/alex/.cargo/registry/src/github.com-1ecc6299db9ec823/sentry-contrib-native-sys-0.3.1/sentry-native" "-DBUILD_SHARED_LIBS=OFF" "-DSENTRY_BUILD_TESTS=OFF" "-DSENTRY_BUILD_EXAMPLES=OFF" "-DSENTRY_BACKEND=crashpad" "-DCRASHPAD_ZLIB_SYSTEM=OFF" "-DCMAKE_INSTALL_PREFIX=/Users/alex/***/target/debug/build/sentry-contrib-native-sys-446c26c5e4b0dd0c/out" "-DCMAKE_C_FLAGS= -ffunction-sections -fdata-sections -fPIC -m64 -arch x86_64" "-DCMAKE_C_COMPILER=/usr/bin/cc" "-DCMAKE_CXX_FLAGS= -ffunction-sections -fdata-sections -fPIC -m64 -arch x86_64" "-DCMAKE_CXX_COMPILER=/usr/bin/c++" "-DCMAKE_ASM_FLAGS= -ffunction-sections -fdata-sections -fPIC -m64 -arch x86_64" "-DCMAKE_ASM_COMPILER=/usr/bin/cc" "-DCMAKE_BUILD_TYPE=RelWithDebInfo"
  -- SENTRY_TRANSPORT=curl
  -- SENTRY_BACKEND=crashpad
  -- SENTRY_LIBRARY_TYPE=STATIC
  -- Configuring incomplete, errors occurred!
  See also "/Users/alex/***/target/debug/build/sentry-contrib-native-sys-446c26c5e4b0dd0c/out/build/CMakeFiles/CMakeOutput.log".
  See also "/Users/alex/***/target/debug/build/sentry-contrib-native-sys-446c26c5e4b0dd0c/out/build/CMakeFiles/CMakeError.log".

  --- stderr
  CMake Error at /usr/local/Cellar/cmake/3.23.0/share/cmake/Modules/FindPackageHandleStandardArgs.cmake:230 (message):
    Could NOT find PythonInterp (missing: PYTHON_EXECUTABLE) (Required is at
    least version "2.7")
  Call Stack (most recent call first):
    /usr/local/Cellar/cmake/3.23.0/share/cmake/Modules/FindPackageHandleStandardArgs.cmake:594 (_FPHSA_FAILURE_MESSAGE)
    /usr/local/Cellar/cmake/3.23.0/share/cmake/Modules/FindPythonInterp.cmake:169 (FIND_PACKAGE_HANDLE_STANDARD_ARGS)
    external/crashpad/util/CMakeLists.txt:354 (find_package)

I think it's fixed in upstream getsentry/sentry-native repo, but I'm not sure how to bump it in here.
Let me know if you need more info or testing!

  • OS: macOS 12.3.1
  • Rust 1.58.1 (db9d1b20b 2022-01-20)

Make cmake optional

I'd like to make building with cmake optional, and default to just using cc to compile all of the C/C++ code. This is mainly due to me wanting to cross compile from linux to windows via clang, which exposes bugs both in some of the cmake scripts for sentry/crashpad/etc, as well as in cmake itself (afaict).

For reference for what this could look like, you can see how we got our physx-rs crate to compile with just cc so that we could just ignore cmake complications altogether.

The work isn't difficult, but I don't know how you would feel about merging such a change so wanted to open this issue before doing any work.

Support for aarch64-apple-darwin?

With the new ARM-powered Mac's coming out next week it would be very nice with support for building this crate for the new aarch64-apple-darwin target, so filing this as a tracking issue towards it but understand it likely would be quite a bit of build system work to do and may need some upstream dependency fixes and support as well.

Since a month ago it is possible to build towards it with nightly with cargo +nightly build --target aarch64-apple-darwin but looks like one runs into build errors with crashpad with it right now

options.init() SIGABRT on macOS 10.15.7

Describe the bug
When running:

let sentry_shutdown: sentry::Shutdown = {
    sentry::set_hook(None, None);

    let mut options = sentry::Options::new();
    options.set_dsn("https://[email protected]/5557394");
    options.set_environment(if config::IS_DEBUG { "debug" } else { "release" });
    options.set_release(config::VERSION);

    // TODO: this crashes on macOS
    options.init().expect("Failed to initialise Sentry")
};

The program SIGABRTs on the last line with the following message:

test(36049,0x1075c8dc0) malloc: *** error for object 0x7f83a0605270: pointer being freed was not allocated
test(36049,0x1075c8dc0) malloc: *** set a breakpoint in malloc_error_break to debug
[1]    36049 abort      ./target/debug/test

The error seems to be coming from crashpad at:

attachments.push_back(base::FilePath(data->event_path->path));

in sentry_backend_crashpad.cpp.

It works fine on Linux.

Environment:

  • OS: macOS 10.15.7
  • Default transport yes
  • Version 0.1.0
  • Rust 1.46.0

Disable using system zlib

When building crashpad, it can optionally use the system zlib, which defaults to true for non-msvc targets, but it would be nice to either disable that entirely and always build from source, or make it an option we could disable via a feature flag, since we would never want to have an additional system dependency when we can compile it from source instead.

Release?

I don't know what more you want to do before doing another release, but would it be possible to make a new one? Or at least a pre-release if you don't want to make a real one?

I'd like to use this in our project, but we can't use git patches due to rust-lang/cargo#8258 and the multiple submodules that are hosted on google code, at least until a new version of cargo is released that has the bugfix in it.

Use event interfaces

Currently Event::add_exception and Event::add_stacktrace don't follow Sentry's exception interface properly.

With sentry-native 0.4.9 this was fixed.
While updating I noticed to adapt to this change in sentry-contrib-native, I will need to do a rather large refactoring. Considering that the original plan was to integrate this into the Sentry's Rust crate, see getsentry/sentry-rust#299, I would like to leave everything as it is, as integration into Sentry's Rust crate will remove these interfaces entirely.

That said, I'm open to any user-input to tell me otherwise.

Build error on Apple M1 Macs + docker

I'm having trouble when building this on M1 macs in docker.

error[E0277]: a value of type `Vec<u8>` cannot be built from an iterator over elements of type `i8`
  --> /usr/local/cargo/registry/src/github.com-1ecc6299db9ec823/sentry-contrib-native-0.3.1/src/ffi.rs:43:55
   |
43 |         path.take_while(|ch| *ch != 0).chain(Some(0)).collect()
   |                                                       ^^^^^^^ value of type `Vec<u8>` cannot be built from `std::iter::Iterator<Item=i8>`
   |
   = help: the trait `FromIterator<i8>` is not implemented for `Vec<u8>`

For more information about this error, try `rustc --explain E0277`.
error: could not compile `sentry-contrib-native` due to previous error

I was able to create a minimal test case that fails the same way on amd64 mac using docker run --platform linux/aarch64 --rm -it rust:1.57 sh
And then running:

apt update && apt install cmake
mkdir foo
cd foo
cargo init
echo 'sentry-contrib-native = "0.3.1"' >> Cargo.toml
cargo b

Changing to --platform linux/amd64 builds fine on M1 (be warned though, the build is super slow).

Environment:

  • OS: macOS 12.1 M1 & amd64
  • sentry-contrib-native 0.3.1
  • Rust 1.57

Let me know if you need more info or help testing/checking stuff!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.