# What does this PR do?
This PR adds support for applications to report unhandled exceptions through the libdatadog crashtracking infrastructure.
I expose an API `report_unhandled_exception` which takes in a complete stacktrace, optional exception message, and optional exception type. It then uses pre-existing functionality to pipe over this data along with other data collected by the crashtracker to the receiver, generating a crash report for unhandled exceptions.
I decide to reuse the current emit code logic and an enum for ErrorKind specific parameters and have conditional logic to decide what to emit based on Kind. This lets us keep the report generation largely unified, making sure that there is no drift.
Another design choice could have been implementing a separate flow to create the crash report piece by piece for unhandled exceptions and upload it directly to an endpoint, but I greatly!!! prefer to reuse a slightly modified emit flow, to minimize drift and ensure parity between to two different "types" of crash reports.
PR below on the stack: [feat(crashtracking): include Kind in crash ping and clarify requirements](#1595 (comment))
PR above on the stack: [feat(crashtracking): unhandled exception reporting FFI](#1597)
# Motivation
# Additional Notes
Example output
```
{
"counters": {
"profiler_inactive": 0,
"profiler_collecting_sample": 0,
"profiler_serializing": 0,
"profiler_unwinding": 0
},
"data_schema_version": "1.5",
"error": {
"is_crash": true,
"kind": "UnhandledException",
"message": "Process was terminated due to an unhandled exception of type 'com.example.UncaughtRuntimeException'. Message: Something went very wrong in the runtime",
"thread_name": "crashtracking_u",
"source_type": "Crashtracking",
"stack": {
"format": "Datadog Crashtracker 1.0",
"frames": [
{
"function": "com.example.MyApp.processRequest"
},
{
"function": "com.example.runtime.EventLoop.run"
},
{
"function": "com.example.runtime.main"
}
],
"incomplete": false
}
},
"experimental": {},
"files": {
"/proc/self/maps": [
"5f06e90e8000-5f06e90e9000 r--p 00000000 103:03 20388557 /home/bits/go/src/github.com/DataDog/libdatadog/examples/ffi/build/crashtracking_unhandled_exception",
"5f06e90e9000-5f06e90ea000 r-xp 00001000 103:03 20388557 /home/bits/go/src/github.com/DataDog/libdatadog/examples/ffi/build/crashtracking_unhandled_exception",
"5f06e90ea000-5f06e90eb000 r--p 00002000 103:03 20388557 /home/bits/go/src/github.com/DataDog/libdatadog/examples/ffi/build/crashtracking_unhandled_exception",
"5f06e90eb000-5f06e90ec000 r--p 00002000 103:03 20388557 /home/bits/go/src/github.com/DataDog/libdatadog/examples/ffi/build/crashtracking_unhandled_exception",
"5f06e90ec000-5f06e90ed000 rw-p 00003000 103:03 20388557 /home/bits/go/src/github.com/DataDog/libdatadog/examples/ffi/build/crashtracking_unhandled_exception",
"5f0706a0b000-5f0706a2c000 rw-p 00000000 00:00 0 [heap]",
"7b23aaec5000-7b23aaec8000 rw-p 00000000 00:00 0 ",
"7b23aaec8000-7b23aaed6000 r--p 00000000 00:33 18157635 /usr/lib/x86_64-linux-gnu/libm.so.6",
"7b23aaed6000-7b23aaf52000 r-xp 0000e000 00:33 18157635 /usr/lib/x86_64-linux-gnu/libm.so.6",
"7b23aaf52000-7b23aafad000 r--p 0008a000 00:33 18157635 /usr/lib/x86_64-linux-gnu/libm.so.6",
"7b23aafad000-7b23aafae000 r--p 000e4000 00:33 18157635 /usr/lib/x86_64-linux-gnu/libm.so.6",
"7b23aafae000-7b23aafaf000 rw-p 000e5000 00:33 18157635 /usr/lib/x86_64-linux-gnu/libm.so.6",
"7b23aafaf000-7b23aafb2000 r--p 00000000 00:33 526021 /usr/lib/x86_64-linux-gnu/libgcc_s.so.1",
"7b23aafb2000-7b23aafc9000 r-xp 00003000 00:33 526021 /usr/lib/x86_64-linux-gnu/libgcc_s.so.1",
"7b23aafc9000-7b23aafcd000 r--p 0001a000 00:33 526021 /usr/lib/x86_64-linux-gnu/libgcc_s.so.1",
"7b23aafcd000-7b23aafce000 r--p 0001d000 00:33 526021 /usr/lib/x86_64-linux-gnu/libgcc_s.so.1",
"7b23aafce000-7b23aafcf000 rw-p 0001e000 00:33 526021 /usr/lib/x86_64-linux-gnu/libgcc_s.so.1",
"7b23aafcf000-7b23aaff7000 r--p 00000000 00:33 18157632 /usr/lib/x86_64-linux-gnu/libc.so.6",
"7b23aaff7000-7b23ab18c000 r-xp 00028000 00:33 18157632 /usr/lib/x86_64-linux-gnu/libc.so.6",
"7b23ab18c000-7b23ab1e4000 r--p 001bd000 00:33 18157632 /usr/lib/x86_64-linux-gnu/libc.so.6",
"7b23ab1e4000-7b23ab1e5000 ---p 00215000 00:33 18157632 /usr/lib/x86_64-linux-gnu/libc.so.6",
"7b23ab1e5000-7b23ab1e9000 r--p 00215000 00:33 18157632 /usr/lib/x86_64-linux-gnu/libc.so.6",
"7b23ab1e9000-7b23ab1eb000 rw-p 00219000 00:33 18157632 /usr/lib/x86_64-linux-gnu/libc.so.6",
"7b23ab1eb000-7b23ab1f8000 rw-p 00000000 00:00 0 ",
"7b23ab200000-7b23ab4be000 r--p 00000000 103:03 19134266 /home/bits/go/src/github.com/DataDog/libdatadog/release/lib/libdatadog_profiling.so",
"7b23ab4be000-7b23abb38000 r-xp 002bd000 103:03 19134266 /home/bits/go/src/github.com/DataDog/libdatadog/release/lib/libdatadog_profiling.so",
"7b23abb38000-7b23abbae000 r--p 00936000 103:03 19134266 /home/bits/go/src/github.com/DataDog/libdatadog/release/lib/libdatadog_profiling.so",
"7b23abbae000-7b23abbb1000 rw-p 009ab000 103:03 19134266 /home/bits/go/src/github.com/DataDog/libdatadog/release/lib/libdatadog_profiling.so",
"7b23abbb1000-7b23abbcf000 rw-p 00000000 00:00 0 ",
"7b23abbcf000-7b23abbd3000 rw-p 00000000 00:00 0 ",
"7b23abbd3000-7b23abbd5000 r--p 00000000 00:33 18157629 /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2",
"7b23abbd5000-7b23abbff000 r-xp 00002000 00:33 18157629 /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2",
"7b23abbff000-7b23abc0a000 r--p 0002c000 00:33 18157629 /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2",
"7b23abc0b000-7b23abc0d000 r--p 00037000 00:33 18157629 /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2",
"7b23abc0d000-7b23abc0f000 rw-p 00039000 00:33 18157629 /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2",
"7ffd13b11000-7ffd13b33000 rw-p 00000000 00:00 0 [stack]",
"7ffd13ba9000-7ffd13bad000 r--p 00000000 00:00 0 [vvar]",
"7ffd13bad000-7ffd13baf000 r-xp 00000000 00:00 0 [vdso]",
"ffffffffff600000-ffffffffff601000 --xp 00000000 00:00 0 [vsyscall]",
""
]
},
"incomplete": false,
"metadata": {
"library_name": "crashtracking-ffi-test",
"library_version": "0.0.0",
"family": "native"
},
"os_info": {
"architecture": "x86_64",
"bitness": "64-bit",
"os_type": "Ubuntu",
"version": "22.4.0"
},
"proc_info": {
"pid": 3794082,
"tid": 3794082
},
"timestamp": "2026-02-18 07:11:37.317056506 UTC",
"uuid": "930d6e20-f14d-42fd-bdac-c4263da9a6ca"
}
```
# How to test the change?
Unit test, bin test, instrument application and emit a crash report for an unhandled exception
Co-authored-by: gyuheon.oh <[email protected]>
What does this PR do?
Add FFI interface for reporting unhandled exception. Also adds tests for it.
The FFI examples test infra part is largely claude code driven
PR below on the stack: feat(crashtracking): report unhandled exceptions
Motivation
What inspired you to submit this pull request?
Additional Notes
Anything else we should know when reviewing?
How to test the change?
Run ffi example tests