-
-
Notifications
You must be signed in to change notification settings - Fork 60
Expand file tree
/
Copy pathCFunctions.cs
More file actions
244 lines (199 loc) · 8.37 KB
/
CFunctions.cs
File metadata and controls
244 lines (199 loc) · 8.37 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using Sentry.Protocol;
using UnityEngine;
namespace Sentry.Unity.Native;
internal static class C
{
#if SENTRY_NATIVE_SWITCH
private const string SentryLib = "__Internal";
#else
private const string SentryLib = "sentry";
#endif
internal static void SetValueIfNotNull(sentry_value_t obj, string key, string? value)
{
if (value is not null)
{
_ = sentry_value_set_by_key(obj, key, sentry_value_new_string(value));
}
}
internal static void SetValueIfNotNull(sentry_value_t obj, string key, int? value)
{
if (value.HasValue)
{
_ = sentry_value_set_by_key(obj, key, sentry_value_new_int32(value.Value));
}
}
internal static void SetValueIfNotNull(sentry_value_t obj, string key, bool? value)
{
if (value.HasValue)
{
_ = sentry_value_set_by_key(obj, key, sentry_value_new_bool(value.Value ? 1 : 0));
}
}
internal static void SetValueIfNotNull(sentry_value_t obj, string key, double? value)
{
if (value.HasValue)
{
_ = sentry_value_set_by_key(obj, key, sentry_value_new_double(value.Value));
}
}
internal static void SetValueIfNotNull(sentry_value_t obj, string key, long? value)
{
if (value.HasValue)
{
_ = sentry_value_set_by_key(obj, key, sentry_value_new_double(value.Value));
}
}
internal static sentry_value_t? GetValueOrNul(sentry_value_t obj, string key)
{
var cValue = sentry_value_get_by_key(obj, key);
return sentry_value_is_null(cValue) == 0 ? cValue : null;
}
internal static string? GetValueString(sentry_value_t obj, string key)
{
if (GetValueOrNul(obj, key) is { } cValue)
{
var cString = sentry_value_as_string(cValue);
if (cString != IntPtr.Zero)
{
return Marshal.PtrToStringAnsi(cString);
}
}
return null;
}
internal static int? GetValueInt(sentry_value_t obj, string key)
{
if (GetValueOrNul(obj, key) is { } cValue)
{
return sentry_value_as_int32(cValue);
}
return null;
}
internal static double? GetValueDouble(sentry_value_t obj, string key)
{
if (GetValueOrNul(obj, key) is { } cValue)
{
return sentry_value_as_double(cValue);
}
return null;
}
[DllImport(SentryLib)]
internal static extern sentry_value_t sentry_value_new_object();
[DllImport(SentryLib)]
internal static extern sentry_value_t sentry_value_new_null();
[DllImport(SentryLib)]
internal static extern sentry_value_t sentry_value_new_bool(int value);
[DllImport(SentryLib)]
internal static extern sentry_value_t sentry_value_new_double(double value);
[DllImport(SentryLib)]
internal static extern sentry_value_t sentry_value_new_int32(int value);
[DllImport(SentryLib)]
internal static extern sentry_value_t sentry_value_new_string(string value);
[DllImport(SentryLib)]
internal static extern sentry_value_t sentry_value_new_breadcrumb(string? type, string? message);
[DllImport(SentryLib)]
internal static extern int sentry_value_set_by_key(sentry_value_t value, string k, sentry_value_t v);
internal static bool IsNull(sentry_value_t value) => sentry_value_is_null(value) != 0;
[DllImport(SentryLib)]
internal static extern int sentry_value_is_null(sentry_value_t value);
[DllImport(SentryLib)]
internal static extern int sentry_value_as_int32(sentry_value_t value);
[DllImport(SentryLib)]
internal static extern double sentry_value_as_double(sentry_value_t value);
[DllImport(SentryLib)]
internal static extern IntPtr sentry_value_as_string(sentry_value_t value);
[DllImport(SentryLib)]
internal static extern UIntPtr sentry_value_get_length(sentry_value_t value);
[DllImport(SentryLib)]
internal static extern sentry_value_t sentry_value_get_by_index(sentry_value_t value, UIntPtr index);
[DllImport(SentryLib)]
internal static extern sentry_value_t sentry_value_get_by_key(sentry_value_t value, string key);
[DllImport(SentryLib)]
internal static extern void sentry_set_context(string key, sentry_value_t value);
[DllImport(SentryLib)]
internal static extern void sentry_add_breadcrumb(sentry_value_t breadcrumb);
[DllImport(SentryLib)]
internal static extern void sentry_set_tag(string key, string value);
[DllImport(SentryLib)]
internal static extern void sentry_remove_tag(string key);
[DllImport(SentryLib)]
internal static extern void sentry_set_user(sentry_value_t user);
[DllImport(SentryLib)]
internal static extern void sentry_remove_user();
[DllImport(SentryLib)]
internal static extern void sentry_set_extra(string key, sentry_value_t value);
[DllImport(SentryLib)]
internal static extern void sentry_remove_extra(string key);
[DllImport(SentryLib)]
internal static extern void sentry_set_trace(string traceId, string parentSpanId);
[DllImport(SentryLib)]
internal static extern IntPtr sentry_attach_file(string path);
[DllImport(SentryLib)]
internal static extern IntPtr sentry_attach_bytes(byte[] buf, UIntPtr buf_len, string filename);
[DllImport(SentryLib)]
internal static extern void sentry_clear_attachments();
internal static readonly Lazy<IEnumerable<DebugImage>> DebugImages = new(LoadDebugImages);
private static IEnumerable<DebugImage> LoadDebugImages()
{
var result = new List<DebugImage>();
try
{
var cList = sentry_get_modules_list();
try
{
if (!IsNull(cList))
{
var len = sentry_value_get_length(cList).ToUInt32();
for (uint i = 0; i < len; i++)
{
var cItem = sentry_value_get_by_index(cList, (UIntPtr)i);
if (!IsNull(cItem))
{
// See possible values present in `cItem` in the following files (or their latest versions)
// * https://github.com/getsentry/sentry-native/blob/8faa78298da68d68043f0c3bd694f756c0e95dfa/src/modulefinder/sentry_modulefinder_windows.c#L81
// * https://github.com/getsentry/sentry-native/blob/8faa78298da68d68043f0c3bd694f756c0e95dfa/src/modulefinder/sentry_modulefinder_windows.c#L24
// * https://github.com/getsentry/sentry-native/blob/c5c31e56d36bed37fa5422750a591f44502edb41/src/modulefinder/sentry_modulefinder_linux.c#L465
result.Add(new DebugImage()
{
CodeFile = GetValueString(cItem, "code_file"),
ImageAddress = Convert.ToInt64(GetValueString(cItem, "image_addr"), 16),
ImageSize = GetValueInt(cItem, "image_size"),
DebugFile = GetValueString(cItem, "debug_file"),
DebugId = GetValueString(cItem, "debug_id"),
CodeId = GetValueString(cItem, "code_id"),
Type = GetValueString(cItem, "type"),
});
}
}
}
}
finally
{
sentry_value_decref(cList);
}
}
catch (Exception e)
{
// Adding the Sentry logger tag ensures we don't send this error to Sentry.
Debug.unityLogger.Log(LogType.Error, UnityLogger.LogTag, $"Error loading the list of debug images: {e}");
}
return result;
}
// Returns a new reference to an immutable, frozen list.
// The reference must be released with `sentry_value_decref`.
[DllImport(SentryLib)]
private static extern sentry_value_t sentry_get_modules_list();
[DllImport(SentryLib)]
internal static extern void sentry_value_decref(sentry_value_t value);
// native union sentry_value_u/t
[StructLayout(LayoutKind.Explicit)]
internal struct sentry_value_t
{
[FieldOffset(0)]
internal ulong _bits;
[FieldOffset(0)]
internal double _double;
}
}