@@ -19,6 +19,7 @@ extern "C" {
19
19
# include " sentry_unix_pageallocator.h"
20
20
#endif
21
21
#include " sentry_utils.h"
22
+ #include " sentry_uuid.h"
22
23
#include " transports/sentry_disk_transport.h"
23
24
}
24
25
@@ -114,9 +115,11 @@ typedef struct {
114
115
sentry_path_t *event_path;
115
116
sentry_path_t *breadcrumb1_path;
116
117
sentry_path_t *breadcrumb2_path;
118
+ sentry_path_t *feedback_path;
117
119
size_t num_breadcrumbs;
118
120
std::atomic<bool > crashed;
119
121
std::atomic<bool > scope_flush;
122
+ sentry_uuid_t crash_event_id;
120
123
} crashpad_state_t ;
121
124
122
125
/* *
@@ -185,7 +188,7 @@ crashpad_register_wer_module(
185
188
#endif
186
189
187
190
static void
188
- crashpad_backend_flush_scope_to_event (const sentry_path_t *event_path,
191
+ flush_scope_to_event (const sentry_path_t *event_path,
189
192
const sentry_options_t *options, sentry_value_t crash_event)
190
193
{
191
194
SENTRY_WITH_SCOPE (scope) {
@@ -196,7 +199,6 @@ crashpad_backend_flush_scope_to_event(const sentry_path_t *event_path,
196
199
197
200
size_t mpack_size;
198
201
char *mpack = sentry_value_to_msgpack (crash_event, &mpack_size);
199
- sentry_value_decref (crash_event);
200
202
if (!mpack) {
201
203
return ;
202
204
}
@@ -209,6 +211,26 @@ crashpad_backend_flush_scope_to_event(const sentry_path_t *event_path,
209
211
}
210
212
}
211
213
214
+ static void
215
+ flush_scope_to_feedback (const sentry_path_t *event_path,
216
+ const sentry_options_t *options, sentry_value_t crash_event)
217
+ {
218
+ sentry_envelope_t *envelope = sentry__envelope_new ();
219
+ if (!envelope) {
220
+ return ;
221
+ }
222
+ sentry__envelope_add_event (envelope, crash_event);
223
+ if (options->session ) {
224
+ sentry__envelope_add_session (envelope, options->session );
225
+ }
226
+
227
+ if (sentry__path_create_dir_all (options->run ->feedback_path ) != 0
228
+ || sentry_envelope_write_to_path (envelope, event_path) != 0 ) {
229
+ SENTRY_WARN (" flushing scope to feedback failed" );
230
+ }
231
+ sentry_envelope_free (envelope);
232
+ }
233
+
212
234
// This function is necessary for macOS since it has no `FirstChanceHandler`.
213
235
// but it is also necessary on Windows if the WER handler is enabled.
214
236
// This means we have to continuously flush the scope on
@@ -234,12 +256,19 @@ crashpad_backend_flush_scope(
234
256
}
235
257
236
258
sentry_value_t event = sentry_value_new_object ();
259
+ sentry_value_set_by_key (
260
+ event, " event_id" , sentry__value_new_uuid (&data->crash_event_id ));
237
261
// Since this will only be uploaded in case of a crash we must make this
238
262
// event fatal.
239
263
sentry_value_set_by_key (
240
264
event, " level" , sentry__value_new_level (SENTRY_LEVEL_FATAL));
241
265
242
- crashpad_backend_flush_scope_to_event (data->event_path , options, event);
266
+ flush_scope_to_event (data->event_path , options, event);
267
+ if (data->feedback_path ) {
268
+ flush_scope_to_feedback (data->feedback_path , options, event);
269
+ } else {
270
+ sentry_value_decref (event);
271
+ }
243
272
data->scope_flush .store (false , std::memory_order_release);
244
273
#endif
245
274
}
@@ -262,8 +291,12 @@ flush_scope_from_handler(
262
291
}
263
292
264
293
// now we are the sole flusher and can flush into the crash event
265
- crashpad_backend_flush_scope_to_event (
266
- state->event_path , options, crash_event);
294
+ flush_scope_to_event (state->event_path , options, crash_event);
295
+ if (state->feedback_path ) {
296
+ flush_scope_to_feedback (state->feedback_path , options, crash_event);
297
+ } else {
298
+ sentry_value_decref (crash_event);
299
+ }
267
300
}
268
301
269
302
# ifdef SENTRY_PLATFORM_WINDOWS
@@ -281,7 +314,9 @@ sentry__crashpad_handler(int signum, siginfo_t *info, ucontext_t *user_context)
281
314
bool should_dump = true ;
282
315
283
316
SENTRY_WITH_OPTIONS (options) {
284
- sentry_value_t crash_event = sentry_value_new_event ();
317
+ auto state = static_cast <crashpad_state_t *>(options->backend ->data );
318
+ sentry_value_t crash_event
319
+ = sentry__value_new_event_with_uuid (&state->crash_event_id );
285
320
sentry_value_set_by_key (
286
321
crash_event, " level" , sentry__value_new_level (SENTRY_LEVEL_FATAL));
287
322
@@ -418,6 +453,9 @@ crashpad_backend_startup(
418
453
sentry_path_t *current_run_folder = options->run ->run_path ;
419
454
auto *data = static_cast <crashpad_state_t *>(backend->data );
420
455
456
+ // prepare a predictable event ID for a potential future crash
457
+ data->crash_event_id = sentry__new_event_id ();
458
+
421
459
base::FilePath database (options->database_path ->path );
422
460
base::FilePath handler (absolute_handler_path->path );
423
461
@@ -455,6 +493,19 @@ crashpad_backend_startup(
455
493
sentry__path_free (screenshot_path);
456
494
}
457
495
496
+ base::FilePath feedback_handler;
497
+ base::FilePath feedback_path;
498
+ if (options->feedback_handler_path ) {
499
+ char *filename
500
+ = sentry__uuid_as_filename (&data->crash_event_id , " .envelope" );
501
+ data->feedback_path
502
+ = sentry__path_join_str (options->run ->feedback_path , filename);
503
+ sentry_free (filename);
504
+
505
+ feedback_handler = base::FilePath (options->feedback_handler_path ->path );
506
+ feedback_path = base::FilePath (data->feedback_path ->path );
507
+ }
508
+
458
509
std::vector<std::string> arguments { " --no-rate-limit" };
459
510
460
511
// Initialize database first, flushing the consent later on as part of
@@ -482,7 +533,7 @@ crashpad_backend_startup(
482
533
minidump_url ? minidump_url : " " , proxy_url, annotations, arguments,
483
534
/* restartable */ true ,
484
535
/* asynchronous_start */ false , attachments, screenshot,
485
- options->crashpad_wait_for_upload );
536
+ options->crashpad_wait_for_upload , feedback_handler, feedback_path );
486
537
sentry_free (minidump_url);
487
538
488
539
#ifdef SENTRY_PLATFORM_WINDOWS
@@ -595,6 +646,7 @@ crashpad_backend_free(sentry_backend_t *backend)
595
646
sentry__path_free (data->event_path );
596
647
sentry__path_free (data->breadcrumb1_path );
597
648
sentry__path_free (data->breadcrumb2_path );
649
+ sentry__path_free (data->feedback_path );
598
650
sentry_free (data);
599
651
}
600
652
0 commit comments