In this Sentry programming session, we looked at using our error monitoring platform to help debug one of our own native products: Symbolicator. This service is responsible for processing native crash reports. Just like any other application, it might crash — and when that happens, we need to gain insights into why.

Crashing Rust

Symbolicator is written in Rust, a language that is loved for its memory-safety. On top of that, the Rust standard library offers extremely well-designed APIs for explicit error handling, making unchecked exceptions a thing of the past. Yet, there are quite a few reasons why a Rust program can still crash, including:

  • The use of unsafe, often used for absolutely necessary optimization.
  • Interop with C and C++, which is inherently unsafe.
  • Stack overflows or out-of-memory situations.

We chose the first option to introduce a very reliable and unfortunately too well-known crash: The infamous segmentation fault. Look at this beauty:

Rust

unsafe { *(0 as *mut u32) = 42; }

This is a slightly modified version of the code we used in the recorded session. It dereferences the null pointer and tries to assign it a value of 42. Totally unsafe, and guaranteed to crash. Fun fact: depending on the optimization level, this line might either cause a segmentation fault or an illegal instruction.

Symbolicator already uses our Rust SDK. It is able to report errors and panics to Sentry, can record breadcrumbs, and can even manage concurrent scopes. However, it cannot handle hard application crashes. For that, we need to haul out the big guns.

#api #debugging #c #rust #native application #programming-c

Debugging a Segfault in Rust
8.00 GEEK