Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

- Temp files are now always created in the configured cache directory. ([#2028](https://github.com/getsentry/symbolicator/pull/2028))
- Filter bogus entry point frames after `__clone` and `__clone3` frames. ([#2040](https://github.com/getsentry/symbolicator/pull/2040))
- Filter nullish outermost frames from stack traces. ([#2041](https://github.com/getsentry/symbolicator/pull/2041))

## 26.8.0

Expand Down
25 changes: 22 additions & 3 deletions crates/symbolicator-native/src/symbolication/symbolicate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ use crate::caches::il2cpp::Il2cppService;
use crate::caches::ppdb_caches::PortablePdbCacheActor;
use crate::caches::symcaches::SymCacheActor;
use crate::interface::{
AdjustInstructionAddr, CompleteStacktrace, CompletedSymbolicationResponse, FrameStatus,
FrameTrust, RawFrame, RawStacktrace, Registers, Signal, SymbolicateStacktraces,
AddrMode, AdjustInstructionAddr, CompleteStacktrace, CompletedSymbolicationResponse,
FrameStatus, FrameTrust, RawFrame, RawStacktrace, Registers, Signal, SymbolicateStacktraces,
SymbolicatedFrame,
};
use crate::memory::MemoryAccess;
Expand Down Expand Up @@ -239,6 +239,9 @@ fn symbolicate_stacktrace(
continue;
}

// Whether this frame is the last (outermost) frame.
let is_outermost_frame = unsymbolicated_frames_iter.peek().is_none();

// Glibc inserts an explicit `DW_CFA_undefined: RIP` DWARF rule to say that frames like
// `_start` have no return address.
// See https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/x86_64/start.S;h=1b3e36826b8a477474cee24d1c931429fbdf6d8f;hb=HEAD#l59
Expand All @@ -250,14 +253,30 @@ fn symbolicate_stacktrace(
// * this is the last frame to symbolicate (via peek)
Comment thread
Dav1dde marked this conversation as resolved.
// * the previous symbolicated frame is a well known frame like `_start`
if status == FrameStatus::UnknownImage
&& unsymbolicated_frames_iter.peek().is_none()
&& is_outermost_frame
&& symbolicated_frames
.last()
.is_some_and(is_likely_glibc_undefined_rip_frame)
{
continue;
}

// Stack traces unwound from a minidump already consider an address from the first page
// practically null and use it as a marker to indicate that stack unwinding is complete.
//
// Stack traces which are unwound on the client side, may still have a frame at the
// end of the stack trace which is null-ish -> remove it here.
let is_nullish =
frame.addr_mode == AddrMode::Abs && frame.instruction_addr.0 < 4096;
if status == FrameStatus::UnknownImage
&& is_outermost_frame
&& is_nullish
// Check for any frames to avoid completely empty stack traces
&& !symbolicated_frames.is_empty()
{
continue;
}
Comment thread
cursor[bot] marked this conversation as resolved.

metrics.unsymbolicated_frames += 1;
match frame.trust {
FrameTrust::Scan => {
Expand Down
Loading