sentry_backtrace/
process.rs1use std::borrow::Cow;
2
3use backtrace::Backtrace;
4use sentry_core::ClientOptions;
5
6use crate::trim::is_well_known_not_in_app;
7use crate::utils::{
8 demangle_symbol, filename, function_starts_with, parse_crate_name, strip_symbol,
9};
10use crate::{Frame, Stacktrace};
11
12pub fn process_event_stacktrace(stacktrace: &mut Stacktrace, options: &ClientOptions) {
16 let mut any_in_app = false;
18 for frame in &mut stacktrace.frames {
19 let func_name = match frame.function {
20 Some(ref func) => func,
21 None => continue,
22 };
23
24 if frame.package.is_none() {
26 frame.package = parse_crate_name(func_name);
27 }
28
29 match frame.in_app {
30 Some(true) => {
31 any_in_app = true;
32 continue;
33 }
34 Some(false) => {
35 continue;
36 }
37 None => {}
38 }
39
40 for m in &options.in_app_include {
41 if function_starts_with(func_name, m) {
42 frame.in_app = Some(true);
43 any_in_app = true;
44 break;
45 }
46 }
47
48 if frame.in_app.is_some() {
49 continue;
50 }
51
52 for m in &options.in_app_exclude {
53 if function_starts_with(func_name, m) {
54 frame.in_app = Some(false);
55 break;
56 }
57 }
58
59 if frame.in_app.is_some() {
60 continue;
61 }
62
63 if is_well_known_not_in_app(func_name) {
64 frame.in_app = Some(false);
65 }
66 }
67
68 if !any_in_app {
69 for frame in &mut stacktrace.frames {
70 if frame.in_app.is_none() {
71 frame.in_app = Some(true);
72 }
73 }
74 }
75}
76
77pub fn backtrace_to_stacktrace(bt: &Backtrace) -> Option<Stacktrace> {
79 let frames = bt
80 .frames()
81 .iter()
82 .flat_map(|frame| {
83 let symbols = frame.symbols();
86 symbols
87 .iter()
88 .map(move |sym| {
89 let abs_path = sym.filename().map(|m| m.to_string_lossy().to_string());
90 let filename = abs_path.as_ref().map(|p| filename(p).to_string());
91 let real_symbol = sym
92 .name()
93 .map_or(Cow::Borrowed("<unknown>"), |n| Cow::Owned(n.to_string()));
94 let symbol = strip_symbol(&real_symbol);
95 let function = demangle_symbol(&symbol);
96 Frame {
97 symbol: if symbol != function {
98 Some(symbol.into())
99 } else {
100 None
101 },
102 function: Some(function),
103 instruction_addr: Some(frame.ip().into()),
104 abs_path,
105 filename,
106 lineno: sym.lineno().map(u64::from),
107 colno: None,
108 ..Default::default()
109 }
110
111 })
114 .chain(if symbols.is_empty() {
115 Some(Frame {
116 instruction_addr: Some(frame.ip().into()),
117 function: Some("<unknown>".into()),
118 ..Default::default()
119 })
120 } else {
121 None
122 })
123 })
124 .collect();
125 Stacktrace::from_frames_reversed(frames)
126}