Skip to content

Commit 9e3dd5e

Browse files
committed
feat: Support attaching bytes
1 parent 455f0ef commit 9e3dd5e

16 files changed

+392
-101
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
**Features**:
66

7-
- The `sentry_attach_file`, `sentry_scope_attach_file` (and their wide-string variants), and `sentry_remove_attachment` have been added to modify the list of attachments that are sent along with sentry events after a call to `sentry_init`. ([#1266](https://github.com/getsentry/sentry-native/pull/1266))
7+
- The `sentry_attach_file/bytes`, `sentry_scope_attach_file/bytes` (and their wide-string variants), and `sentry_remove_attachment` have been added to modify the list of attachments that are sent along with sentry events after a call to `sentry_init`. ([#1266](https://github.com/getsentry/sentry-native/pull/1266), [#1275](https://github.com/getsentry/sentry-native/pull/1275))
88
- NOTE: When using the `crashpad` backend on macOS, the list of attachments that will be added at the time of a hard crash will be frozen at the time of `sentry_init`, and later modifications will not be reflected.
99
- Add `sentry_attachment_set_content_type` to allow specifying the content type of attachments. ([#1276](https://github.com/getsentry/sentry-native/pull/1276))
1010

include/sentry.h

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1793,15 +1793,15 @@ struct sentry_attachment_s;
17931793
typedef struct sentry_attachment_s sentry_attachment_t;
17941794

17951795
/**
1796-
* Adds a new attachment to be sent along.
1796+
* Attaches a file to be sent along with events.
17971797
*
17981798
* `path` is assumed to be in platform-specific filesystem path encoding.
17991799
* API Users on windows are encouraged to use `sentry_attach_filew` or
18001800
* `sentry_scope_attach_filew` instead.
18011801
*
18021802
* The returned `sentry_attachment_t` is owned by the SDK and will remain valid
18031803
* until the attachment is removed with `sentry_remove_attachment` or
1804-
* `sentry_close` is called
1804+
* `sentry_close` is called.
18051805
*
18061806
* See the NOTE on attachments above for restrictions of this API.
18071807
*/
@@ -1813,6 +1813,29 @@ SENTRY_API sentry_attachment_t *sentry_scope_attach_file(
18131813
SENTRY_API sentry_attachment_t *sentry_scope_attach_file_n(
18141814
sentry_scope_t *scope, const char *path, size_t path_len);
18151815

1816+
/**
1817+
* Attaches bytes to be sent along with events.
1818+
*
1819+
* `filename` is assumed to be in platform-specific filesystem path encoding.
1820+
* API Users on windows are encouraged to use `sentry_attach_bytesw` or
1821+
* `sentry_scope_attach_bytesw` instead.
1822+
*
1823+
* The returned `sentry_attachment_t` is owned by the SDK and will remain valid
1824+
* until the attachment is removed with `sentry_remove_attachment` or
1825+
* `sentry_close` is called.
1826+
*
1827+
* See the NOTE on attachments above for restrictions of this API.
1828+
*/
1829+
SENTRY_API sentry_attachment_t *sentry_attach_bytes(
1830+
const char *buf, size_t buf_len, const char *filename);
1831+
SENTRY_API sentry_attachment_t *sentry_attach_bytes_n(
1832+
const char *buf, size_t buf_len, const char *filename, size_t filename_len);
1833+
SENTRY_API sentry_attachment_t *sentry_scope_attach_bytes(sentry_scope_t *scope,
1834+
const char *buf, size_t buf_len, const char *filename);
1835+
SENTRY_API sentry_attachment_t *sentry_scope_attach_bytes_n(
1836+
sentry_scope_t *scope, const char *buf, size_t buf_len,
1837+
const char *filename, size_t filename_len);
1838+
18161839
/**
18171840
* Removes and frees a previously added attachment.
18181841
*
@@ -1831,6 +1854,20 @@ SENTRY_API sentry_attachment_t *sentry_scope_attach_filew(
18311854
sentry_scope_t *scope, const wchar_t *path);
18321855
SENTRY_API sentry_attachment_t *sentry_scope_attach_filew_n(
18331856
sentry_scope_t *scope, const wchar_t *path, size_t path_len);
1857+
1858+
/**
1859+
* Wide char versions of `sentry_attach_bytes` and `sentry_scope_attach_bytes`.
1860+
*/
1861+
SENTRY_API sentry_attachment_t *sentry_attach_bytesw(
1862+
const char *buf, size_t buf_len, const wchar_t *filename);
1863+
SENTRY_API sentry_attachment_t *sentry_attach_bytesw_n(const char *buf,
1864+
size_t buf_len, const wchar_t *filename, size_t filename_len);
1865+
SENTRY_API sentry_attachment_t *sentry_scope_attach_bytesw(
1866+
sentry_scope_t *scope, const char *buf, size_t buf_len,
1867+
const wchar_t *filename);
1868+
SENTRY_API sentry_attachment_t *sentry_scope_attach_bytesw_n(
1869+
sentry_scope_t *scope, const char *buf, size_t buf_len,
1870+
const wchar_t *filename, size_t filename_len);
18341871
#endif
18351872

18361873
SENTRY_API void sentry_attachment_set_content_type(

src/backends/sentry_backend_breakpad.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ extern "C" {
22
#include "sentry_boot.h"
33

44
#include "sentry_alloc.h"
5+
#include "sentry_attachment.h"
56
#include "sentry_backend.h"
67
#include "sentry_core.h"
78
#include "sentry_database.h"
@@ -169,8 +170,8 @@ breakpad_backend_callback(const google_breakpad::MinidumpDescriptor &descriptor,
169170
sentry_path_t *screenshot_path
170171
= sentry__screenshot_get_path(options);
171172
if (sentry__screenshot_capture(screenshot_path)) {
172-
sentry__envelope_add_attachment(
173-
envelope, screenshot_path, ATTACHMENT, nullptr);
173+
sentry__envelope_add_attachment(envelope,
174+
sentry__attachment_from_path(screenshot_path));
174175
}
175176
sentry__path_free(screenshot_path);
176177
}

src/backends/sentry_backend_crashpad.cpp

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -662,26 +662,52 @@ crashpad_backend_prune_database(sentry_backend_t *backend)
662662
}
663663

664664
#if defined(SENTRY_PLATFORM_WINDOWS) || defined(SENTRY_PLATFORM_LINUX)
665+
static crashpad::UUID
666+
to_crashpad_uuid(const sentry_uuid_t *uuid)
667+
{
668+
char str[37];
669+
sentry_uuid_as_string(uuid, str);
670+
671+
crashpad::UUID rv;
672+
rv.InitializeFromString(str);
673+
return rv;
674+
}
675+
676+
static crashpad::Attachment
677+
to_crashpad_attachment(const sentry_attachment_t *attachment)
678+
{
679+
if (attachment->buf) {
680+
uint8_t *buf = reinterpret_cast<uint8_t *>(attachment->buf);
681+
return crashpad::Attachment(
682+
std::vector<uint8_t>(buf, buf + attachment->buf_len),
683+
base::FilePath(attachment->path->path),
684+
to_crashpad_uuid(&attachment->uuid));
685+
}
686+
687+
return crashpad::Attachment(base::FilePath(attachment->path->path),
688+
to_crashpad_uuid(&attachment->uuid));
689+
}
690+
665691
static void
666692
crashpad_backend_add_attachment(
667-
sentry_backend_t *backend, const sentry_path_t *attachment)
693+
sentry_backend_t *backend, const sentry_attachment_t *attachment)
668694
{
669695
auto *data = static_cast<crashpad_state_t *>(backend->data);
670696
if (!data || !data->client) {
671697
return;
672698
}
673-
data->client->AddAttachment(base::FilePath(attachment->path));
699+
data->client->AddAttachment(to_crashpad_attachment(attachment));
674700
}
675701

676702
static void
677703
crashpad_backend_remove_attachment(
678-
sentry_backend_t *backend, const sentry_path_t *attachment)
704+
sentry_backend_t *backend, const sentry_attachment_t *attachment)
679705
{
680706
auto *data = static_cast<crashpad_state_t *>(backend->data);
681707
if (!data || !data->client) {
682708
return;
683709
}
684-
data->client->RemoveAttachment(base::FilePath(attachment->path));
710+
data->client->RemoveAttachment(to_crashpad_uuid(&attachment->uuid));
685711
}
686712
#endif
687713

src/backends/sentry_backend_inproc.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#include "sentry_attachment.h"
12
#include "sentry_boot.h"
23

34
#include "sentry_alloc.h"
@@ -601,8 +602,8 @@ handle_ucontext(const sentry_ucontext_t *uctx)
601602
sentry_path_t *screenshot_path
602603
= sentry__screenshot_get_path(options);
603604
if (sentry__screenshot_capture(screenshot_path)) {
604-
sentry__envelope_add_attachment(
605-
envelope, screenshot_path, ATTACHMENT, NULL);
605+
sentry__envelope_add_attachment(envelope,
606+
sentry__attachment_from_path(screenshot_path));
606607
}
607608
sentry__path_free(screenshot_path);
608609
}

src/sentry_attachment.c

Lines changed: 88 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
#include "sentry_path.h"
44
#include "sentry_string.h"
55

6+
#include <string.h>
7+
68
void
79
sentry_attachment_set_content_type(
810
sentry_attachment_t *attachment, const char *content_type)
@@ -24,13 +26,49 @@ sentry_attachment_set_content_type_n(sentry_attachment_t *attachment,
2426
= sentry__string_clone_n(content_type, content_type_len);
2527
}
2628

29+
sentry_attachment_t *
30+
sentry__attachment_from_path(sentry_path_t *path)
31+
{
32+
if (!path) {
33+
return NULL;
34+
}
35+
sentry_attachment_t *attachment = SENTRY_MAKE(sentry_attachment_t);
36+
if (!attachment) {
37+
sentry__path_free(path);
38+
return NULL;
39+
}
40+
memset(attachment, 0, sizeof(sentry_attachment_t));
41+
attachment->path = path;
42+
attachment->uuid = sentry_uuid_new_v4();
43+
return attachment;
44+
}
45+
46+
sentry_attachment_t *
47+
sentry__attachment_from_buffer(
48+
const char *buf, size_t buf_len, sentry_path_t *filename)
49+
{
50+
if (!buf || !buf_len || !filename) {
51+
sentry__path_free(filename);
52+
return NULL;
53+
}
54+
sentry_attachment_t *attachment = sentry__attachment_from_path(filename);
55+
if (!attachment) {
56+
return NULL;
57+
}
58+
attachment->buf = sentry_malloc(buf_len * sizeof(char));
59+
memcpy(attachment->buf, buf, buf_len * sizeof(char));
60+
attachment->buf_len = buf_len;
61+
return attachment;
62+
}
63+
2764
static void
2865
attachment_free(sentry_attachment_t *attachment)
2966
{
3067
if (!attachment) {
3168
return;
3269
}
3370
sentry__path_free(attachment->path);
71+
sentry_free(attachment->buf);
3472
sentry_free(attachment->content_type);
3573
sentry_free(attachment);
3674
}
@@ -47,28 +85,34 @@ sentry__attachments_free(sentry_attachment_t *attachments)
4785
}
4886
}
4987

88+
static bool
89+
attachment_eq(const sentry_attachment_t *a, const sentry_attachment_t *b)
90+
{
91+
if (a == b) {
92+
return true;
93+
}
94+
if (!a || !b || !a->path || !b->path || a->type != b->type
95+
|| a->content_type != b->content_type) {
96+
return false;
97+
}
98+
return sentry__path_eq(a->path, b->path);
99+
}
100+
50101
sentry_attachment_t *
51102
sentry__attachments_add(sentry_attachment_t **attachments_ptr,
52-
sentry_path_t *path, sentry_attachment_type_t attachment_type,
103+
sentry_attachment_t *attachment, sentry_attachment_type_t attachment_type,
53104
const char *content_type)
54105
{
55-
if (!path) {
56-
return NULL;
57-
}
58-
sentry_attachment_t *attachment = SENTRY_MAKE(sentry_attachment_t);
59106
if (!attachment) {
60-
sentry__path_free(path);
61107
return NULL;
62108
}
63-
attachment->path = path;
64-
attachment->next = NULL;
65109
attachment->type = attachment_type;
66110
attachment->content_type = sentry__string_clone(content_type);
67111

68112
sentry_attachment_t **next_ptr = attachments_ptr;
69113

70114
for (sentry_attachment_t *it = *attachments_ptr; it; it = it->next) {
71-
if (sentry__path_eq(it->path, path)) {
115+
if (attachment_eq(it, attachment)) {
72116
attachment_free(attachment);
73117
return it;
74118
}
@@ -91,7 +135,7 @@ sentry__attachments_remove(
91135
sentry_attachment_t **next_ptr = attachments_ptr;
92136

93137
for (sentry_attachment_t *it = *attachments_ptr; it; it = it->next) {
94-
if (it == attachment || sentry__path_eq(it->path, attachment->path)) {
138+
if (attachment_eq(it, attachment)) {
95139
*next_ptr = it->next;
96140
attachment_free(it);
97141
return;
@@ -101,12 +145,44 @@ sentry__attachments_remove(
101145
}
102146
}
103147

148+
static sentry_attachment_t *
149+
attachment_clone(const sentry_attachment_t *attachment)
150+
{
151+
if (!attachment) {
152+
return NULL;
153+
}
154+
155+
sentry_attachment_t *clone = SENTRY_MAKE(sentry_attachment_t);
156+
if (!clone) {
157+
return NULL;
158+
}
159+
memset(clone, 0, sizeof(sentry_attachment_t));
160+
161+
if (attachment->path) {
162+
clone->path = sentry__path_clone(attachment->path);
163+
}
164+
if (attachment->buf_len > 0) {
165+
clone->buf_len = attachment->buf_len;
166+
clone->buf = sentry_malloc(attachment->buf_len * sizeof(char));
167+
if (!clone->buf) {
168+
attachment_free(clone);
169+
return NULL;
170+
}
171+
memcpy(clone->buf, attachment->buf, attachment->buf_len * sizeof(char));
172+
}
173+
clone->type = attachment->type;
174+
clone->content_type = attachment->content_type;
175+
clone->uuid = attachment->uuid;
176+
177+
return clone;
178+
}
179+
104180
void
105181
sentry__attachments_extend(
106182
sentry_attachment_t **attachments_ptr, sentry_attachment_t *attachments)
107183
{
108184
for (sentry_attachment_t *it = attachments; it; it = it->next) {
109-
sentry__attachments_add(attachments_ptr, sentry__path_clone(it->path),
110-
it->type, it->content_type);
185+
sentry__attachments_add(
186+
attachments_ptr, attachment_clone(it), it->type, it->content_type);
111187
}
112188
}

src/sentry_attachment.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,18 @@ typedef enum {
2020
*/
2121
struct sentry_attachment_s {
2222
sentry_path_t *path;
23+
char *buf;
24+
size_t buf_len;
2325
sentry_attachment_type_t type;
2426
char *content_type;
27+
sentry_uuid_t uuid;
2528
sentry_attachment_t *next;
2629
};
2730

31+
sentry_attachment_t *sentry__attachment_from_path(sentry_path_t *path);
32+
sentry_attachment_t *sentry__attachment_from_buffer(
33+
const char *buf, size_t buf_len, sentry_path_t *filename);
34+
2835
/**
2936
* Frees the linked list of `attachments`.
3037
*/
@@ -34,7 +41,7 @@ void sentry__attachments_free(sentry_attachment_t *attachments);
3441
* Adds an attachment to the attachments list at `attachments_ptr`.
3542
*/
3643
sentry_attachment_t *sentry__attachments_add(
37-
sentry_attachment_t **attachments_ptr, sentry_path_t *path,
44+
sentry_attachment_t **attachments_ptr, sentry_attachment_t *attachment,
3845
sentry_attachment_type_t attachment_type, const char *content_type);
3946

4047
/**

src/sentry_backend.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,10 @@ struct sentry_backend_s {
2525
void (*user_consent_changed_func)(sentry_backend_t *);
2626
uint64_t (*get_last_crash_func)(sentry_backend_t *);
2727
void (*prune_database_func)(sentry_backend_t *);
28-
void (*add_attachment_func)(sentry_backend_t *, const sentry_path_t *);
29-
void (*remove_attachment_func)(sentry_backend_t *, const sentry_path_t *);
28+
void (*add_attachment_func)(
29+
sentry_backend_t *, const sentry_attachment_t *);
30+
void (*remove_attachment_func)(
31+
sentry_backend_t *, const sentry_attachment_t *);
3032
void *data;
3133
// Whether this backend still runs after shutdown_func was called.
3234
bool can_capture_after_shutdown;

0 commit comments

Comments
 (0)