From 1bcfc3f2ad600ba28c3058abe6aafe7575f25ee1 Mon Sep 17 00:00:00 2001 From: Arpad Borsos Date: Wed, 30 Mar 2022 19:56:43 +0200 Subject: [PATCH] feat: Add new Protocol for DebugImages and AddressMode (#1513) Co-authored-by: Simon Cropp Co-authored-by: Bruno Garcia --- CHANGELOG.md | 1 + src/Sentry/DebugImage.cs | 92 +++++++++++++++++++ src/Sentry/Exceptions/SentryStackFrame.cs | 13 ++- src/Sentry/SentryEvent.cs | 20 ++++ .../ApiApprovalTests.Run.Core3_1.verified.txt | 15 +++ ...piApprovalTests.Run.DotNet5_0.verified.txt | 15 +++ ...piApprovalTests.Run.DotNet6_0.verified.txt | 15 +++ .../ApiApprovalTests.Run.Core2_1.verified.txt | 15 +++ .../ApiApprovalTests.Run.Core3_0.verified.txt | 15 +++ .../ApiApprovalTests.Run.Core3_1.verified.txt | 15 +++ ...piApprovalTests.Run.DotNet4_6.verified.txt | 15 +++ ...piApprovalTests.Run.DotNet5_0.verified.txt | 15 +++ ...piApprovalTests.Run.DotNet6_0.verified.txt | 15 +++ test/Sentry.Tests/Protocol/DebugImageTests.cs | 39 ++++++++ .../Exceptions/SentryStackFrameTests.cs | 13 ++- .../Sentry.Tests/Protocol/SentryEventTests.cs | 9 ++ 16 files changed, 317 insertions(+), 5 deletions(-) create mode 100644 src/Sentry/DebugImage.cs create mode 100644 test/Sentry.Tests/Protocol/DebugImageTests.cs diff --git a/CHANGELOG.md b/CHANGELOG.md index 7ecbe02988..46c45d365d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ### Features - Use a default value of 60 seconds if a `Retry-After` header is not present. ([#1537](https://github.com/getsentry/sentry-dotnet/pull/1537)) +- Add new Protocol definitions for DebugImages and AddressMode ([#1513](https://github.com/getsentry/sentry-dotnet/pull/1513)) ### Fixes diff --git a/src/Sentry/DebugImage.cs b/src/Sentry/DebugImage.cs new file mode 100644 index 0000000000..6d8fc67e27 --- /dev/null +++ b/src/Sentry/DebugImage.cs @@ -0,0 +1,92 @@ +using System.Text.Json; +using Sentry.Extensibility; +using Sentry.Internal.Extensions; + +namespace Sentry +{ + /// + /// The Sentry Debug Meta Images interface. + /// + /// + public sealed class DebugImage : IJsonSerializable + { + /// + /// Type of the debug image. + /// + public string? Type { get; set; } + + /// + /// Memory address, at which the image is mounted in the virtual address space of the process. + /// Should be a string in hex representation prefixed with "0x". + /// + public string? ImageAddress { get; set; } + + /// + /// The size of the image in virtual memory. + /// If missing, Sentry will assume that the image spans up to the next image, which might lead to invalid stack traces. + /// + public long? ImageSize { get; set; } + + /// + /// Unique debug identifier of the image. + /// + public string? DebugId { get; set; } + + /// + /// Path and name of the debug companion file. + /// + public string? DebugFile { get; set; } + + /// + /// Optional identifier of the code file. + /// + public string? CodeId { get; set; } + + /// + /// The absolute path to the dynamic library or executable. + /// This helps to locate the file if it is missing on Sentry. + /// + public string? CodeFile { get; set; } + + /// + public void WriteTo(Utf8JsonWriter writer, IDiagnosticLogger? logger) + { + writer.WriteStartObject(); + + writer.WriteStringIfNotWhiteSpace("type", Type); + writer.WriteStringIfNotWhiteSpace("image_addr", ImageAddress); + writer.WriteNumberIfNotNull("image_size", ImageSize); + writer.WriteStringIfNotWhiteSpace("debug_id", DebugId); + writer.WriteStringIfNotWhiteSpace("debug_file", DebugFile); + writer.WriteStringIfNotWhiteSpace("code_id", CodeId); + writer.WriteStringIfNotWhiteSpace("code_file", CodeFile); + + writer.WriteEndObject(); + } + + /// + /// Parses from JSON. + /// + public static DebugImage FromJson(JsonElement json) + { + var type = json.GetPropertyOrNull("type")?.GetString(); + var imageAddress = json.GetPropertyOrNull("image_addr")?.GetString(); + var imageSize = json.GetPropertyOrNull("image_size")?.GetInt64(); + var debugId = json.GetPropertyOrNull("debug_id")?.GetString(); + var debugFile = json.GetPropertyOrNull("debug_file")?.GetString(); + var codeId = json.GetPropertyOrNull("code_id")?.GetString(); + var codeFile = json.GetPropertyOrNull("code_file")?.GetString(); + + return new DebugImage + { + Type = type, + ImageAddress = imageAddress, + ImageSize = imageSize, + DebugId = debugId, + DebugFile = debugFile, + CodeId = codeId, + CodeFile = codeFile, + }; + } + } +} diff --git a/src/Sentry/Exceptions/SentryStackFrame.cs b/src/Sentry/Exceptions/SentryStackFrame.cs index 85944f674c..b93d0a0eb7 100644 --- a/src/Sentry/Exceptions/SentryStackFrame.cs +++ b/src/Sentry/Exceptions/SentryStackFrame.cs @@ -134,6 +134,14 @@ public sealed class SentryStackFrame : IJsonSerializable /// public long? InstructionOffset { get; set; } + /// + /// Optionally changes the addressing mode. The default value is the same as + /// `"abs"` which means absolute referencing. This can also be set to + /// `"rel:DEBUG_ID"` or `"rel:IMAGE_INDEX"` to make addresses relative to an + /// object referenced by debug id or index. + /// + public string? AddressMode { get; set; } + /// public void WriteTo(Utf8JsonWriter writer, IDiagnosticLogger? logger) { @@ -157,6 +165,7 @@ public void WriteTo(Utf8JsonWriter writer, IDiagnosticLogger? logger) writer.WriteNumberIfNotNull("symbol_addr", SymbolAddress); writer.WriteStringIfNotWhiteSpace("instruction_addr", InstructionAddress); writer.WriteNumberIfNotNull("instruction_offset", InstructionOffset); + writer.WriteStringIfNotWhiteSpace("addr_mode", AddressMode); writer.WriteEndObject(); } @@ -207,6 +216,7 @@ public static SentryStackFrame FromJson(JsonElement json) var symbolAddress = json.GetPropertyOrNull("symbol_addr")?.GetInt64(); var instructionAddress = json.GetPropertyOrNull("instruction_addr")?.GetString(); var instructionOffset = json.GetPropertyOrNull("instruction_offset")?.GetInt64(); + var addressMode = json.GetPropertyOrNull("addr_mode")?.GetString(); return new SentryStackFrame { @@ -227,7 +237,8 @@ public static SentryStackFrame FromJson(JsonElement json) ImageAddress = imageAddress, SymbolAddress = symbolAddress, InstructionAddress = instructionAddress, - InstructionOffset = instructionOffset + InstructionOffset = instructionOffset, + AddressMode = addressMode, }; } } diff --git a/src/Sentry/SentryEvent.cs b/src/Sentry/SentryEvent.cs index c32ae082f2..02c136fd31 100644 --- a/src/Sentry/SentryEvent.cs +++ b/src/Sentry/SentryEvent.cs @@ -96,6 +96,12 @@ public IEnumerable? SentryThreads set => SentryThreadValues = value != null ? new SentryValues(value) : null; } + /// + /// The Sentry Debug Meta Images interface. + /// + /// + public List? DebugImages { get; set; } + /// /// A list of relevant modules and their versions. /// @@ -242,6 +248,16 @@ public void WriteTo(Utf8JsonWriter writer, IDiagnosticLogger? logger) writer.WriteDictionaryIfNotEmpty("extra", _extra, logger); writer.WriteStringDictionaryIfNotEmpty("tags", _tags!); + if (DebugImages?.Count > 0) + { + writer.WritePropertyName("debug_meta"); + writer.WriteStartObject(); + + writer.WriteArray("images", DebugImages.ToArray(), logger); + + writer.WriteEndObject(); + } + writer.WriteEndObject(); } @@ -272,6 +288,9 @@ public static SentryEvent FromJson(JsonElement json) var extra = json.GetPropertyOrNull("extra")?.GetDictionaryOrNull(); var tags = json.GetPropertyOrNull("tags")?.GetStringDictionaryOrNull(); + var debugMeta = json.GetPropertyOrNull("debug_meta"); + var images = debugMeta?.GetPropertyOrNull("images")?.EnumerateArray().Select(DebugImage.FromJson).ToList(); + return new SentryEvent(null, timestamp, eventId) { _modules = modules?.WhereNotNullValue().ToDictionary(), @@ -282,6 +301,7 @@ public static SentryEvent FromJson(JsonElement json) Release = release, SentryExceptionValues = exceptionValues, SentryThreadValues = threadValues, + DebugImages = images, Level = level, TransactionName = transaction, _request = request, diff --git a/test/Sentry.DiagnosticSource.Tests/ApiApprovalTests.Run.Core3_1.verified.txt b/test/Sentry.DiagnosticSource.Tests/ApiApprovalTests.Run.Core3_1.verified.txt index 5c965ff1ab..a3202bd7e4 100644 --- a/test/Sentry.DiagnosticSource.Tests/ApiApprovalTests.Run.Core3_1.verified.txt +++ b/test/Sentry.DiagnosticSource.Tests/ApiApprovalTests.Run.Core3_1.verified.txt @@ -70,6 +70,19 @@ namespace Sentry public void WriteTo(System.Text.Json.Utf8JsonWriter writer, Sentry.Extensibility.IDiagnosticLogger? logger) { } public static Sentry.Contexts FromJson(System.Text.Json.JsonElement json) { } } + public sealed class DebugImage : Sentry.IJsonSerializable + { + public DebugImage() { } + public string? CodeFile { get; set; } + public string? CodeId { get; set; } + public string? DebugFile { get; set; } + public string? DebugId { get; set; } + public string? ImageAddress { get; set; } + public long? ImageSize { get; set; } + public string? Type { get; set; } + public void WriteTo(System.Text.Json.Utf8JsonWriter writer, Sentry.Extensibility.IDiagnosticLogger? logger) { } + public static Sentry.DebugImage FromJson(System.Text.Json.JsonElement json) { } + } [System.Flags] public enum DeduplicateMode { @@ -362,6 +375,7 @@ namespace Sentry public SentryEvent(System.Exception? exception) { } public System.Collections.Generic.IReadOnlyCollection Breadcrumbs { get; } public Sentry.Contexts Contexts { get; set; } + public System.Collections.Generic.List? DebugImages { get; set; } public string? Environment { get; set; } public Sentry.SentryId EventId { get; } public System.Exception? Exception { get; } @@ -556,6 +570,7 @@ namespace Sentry { public SentryStackFrame() { } public string? AbsolutePath { get; set; } + public string? AddressMode { get; set; } public int? ColumnNumber { get; set; } public string? ContextLine { get; set; } public string? FileName { get; set; } diff --git a/test/Sentry.DiagnosticSource.Tests/ApiApprovalTests.Run.DotNet5_0.verified.txt b/test/Sentry.DiagnosticSource.Tests/ApiApprovalTests.Run.DotNet5_0.verified.txt index 52dfab4018..1cd928a201 100644 --- a/test/Sentry.DiagnosticSource.Tests/ApiApprovalTests.Run.DotNet5_0.verified.txt +++ b/test/Sentry.DiagnosticSource.Tests/ApiApprovalTests.Run.DotNet5_0.verified.txt @@ -70,6 +70,19 @@ namespace Sentry public void WriteTo(System.Text.Json.Utf8JsonWriter writer, Sentry.Extensibility.IDiagnosticLogger? logger) { } public static Sentry.Contexts FromJson(System.Text.Json.JsonElement json) { } } + public sealed class DebugImage : Sentry.IJsonSerializable + { + public DebugImage() { } + public string? CodeFile { get; set; } + public string? CodeId { get; set; } + public string? DebugFile { get; set; } + public string? DebugId { get; set; } + public string? ImageAddress { get; set; } + public long? ImageSize { get; set; } + public string? Type { get; set; } + public void WriteTo(System.Text.Json.Utf8JsonWriter writer, Sentry.Extensibility.IDiagnosticLogger? logger) { } + public static Sentry.DebugImage FromJson(System.Text.Json.JsonElement json) { } + } [System.Flags] public enum DeduplicateMode { @@ -362,6 +375,7 @@ namespace Sentry public SentryEvent(System.Exception? exception) { } public System.Collections.Generic.IReadOnlyCollection Breadcrumbs { get; } public Sentry.Contexts Contexts { get; set; } + public System.Collections.Generic.List? DebugImages { get; set; } public string? Environment { get; set; } public Sentry.SentryId EventId { get; } public System.Exception? Exception { get; } @@ -556,6 +570,7 @@ namespace Sentry { public SentryStackFrame() { } public string? AbsolutePath { get; set; } + public string? AddressMode { get; set; } public int? ColumnNumber { get; set; } public string? ContextLine { get; set; } public string? FileName { get; set; } diff --git a/test/Sentry.DiagnosticSource.Tests/ApiApprovalTests.Run.DotNet6_0.verified.txt b/test/Sentry.DiagnosticSource.Tests/ApiApprovalTests.Run.DotNet6_0.verified.txt index 7d15fad0ba..b1e3816664 100644 --- a/test/Sentry.DiagnosticSource.Tests/ApiApprovalTests.Run.DotNet6_0.verified.txt +++ b/test/Sentry.DiagnosticSource.Tests/ApiApprovalTests.Run.DotNet6_0.verified.txt @@ -70,6 +70,19 @@ namespace Sentry public void WriteTo(System.Text.Json.Utf8JsonWriter writer, Sentry.Extensibility.IDiagnosticLogger? logger) { } public static Sentry.Contexts FromJson(System.Text.Json.JsonElement json) { } } + public sealed class DebugImage : Sentry.IJsonSerializable + { + public DebugImage() { } + public string? CodeFile { get; set; } + public string? CodeId { get; set; } + public string? DebugFile { get; set; } + public string? DebugId { get; set; } + public string? ImageAddress { get; set; } + public long? ImageSize { get; set; } + public string? Type { get; set; } + public void WriteTo(System.Text.Json.Utf8JsonWriter writer, Sentry.Extensibility.IDiagnosticLogger? logger) { } + public static Sentry.DebugImage FromJson(System.Text.Json.JsonElement json) { } + } [System.Flags] public enum DeduplicateMode { @@ -362,6 +375,7 @@ namespace Sentry public SentryEvent(System.Exception? exception) { } public System.Collections.Generic.IReadOnlyCollection Breadcrumbs { get; } public Sentry.Contexts Contexts { get; set; } + public System.Collections.Generic.List? DebugImages { get; set; } public string? Environment { get; set; } public Sentry.SentryId EventId { get; } public System.Exception? Exception { get; } @@ -556,6 +570,7 @@ namespace Sentry { public SentryStackFrame() { } public string? AbsolutePath { get; set; } + public string? AddressMode { get; set; } public int? ColumnNumber { get; set; } public string? ContextLine { get; set; } public string? FileName { get; set; } diff --git a/test/Sentry.Tests/ApiApprovalTests.Run.Core2_1.verified.txt b/test/Sentry.Tests/ApiApprovalTests.Run.Core2_1.verified.txt index 617e44983b..17352caed4 100644 --- a/test/Sentry.Tests/ApiApprovalTests.Run.Core2_1.verified.txt +++ b/test/Sentry.Tests/ApiApprovalTests.Run.Core2_1.verified.txt @@ -70,6 +70,19 @@ namespace Sentry public void WriteTo(System.Text.Json.Utf8JsonWriter writer, Sentry.Extensibility.IDiagnosticLogger? logger) { } public static Sentry.Contexts FromJson(System.Text.Json.JsonElement json) { } } + public sealed class DebugImage : Sentry.IJsonSerializable + { + public DebugImage() { } + public string? CodeFile { get; set; } + public string? CodeId { get; set; } + public string? DebugFile { get; set; } + public string? DebugId { get; set; } + public string? ImageAddress { get; set; } + public long? ImageSize { get; set; } + public string? Type { get; set; } + public void WriteTo(System.Text.Json.Utf8JsonWriter writer, Sentry.Extensibility.IDiagnosticLogger? logger) { } + public static Sentry.DebugImage FromJson(System.Text.Json.JsonElement json) { } + } [System.Flags] public enum DeduplicateMode { @@ -362,6 +375,7 @@ namespace Sentry public SentryEvent(System.Exception? exception) { } public System.Collections.Generic.IReadOnlyCollection Breadcrumbs { get; } public Sentry.Contexts Contexts { get; set; } + public System.Collections.Generic.List? DebugImages { get; set; } public string? Environment { get; set; } public Sentry.SentryId EventId { get; } public System.Exception? Exception { get; } @@ -555,6 +569,7 @@ namespace Sentry { public SentryStackFrame() { } public string? AbsolutePath { get; set; } + public string? AddressMode { get; set; } public int? ColumnNumber { get; set; } public string? ContextLine { get; set; } public string? FileName { get; set; } diff --git a/test/Sentry.Tests/ApiApprovalTests.Run.Core3_0.verified.txt b/test/Sentry.Tests/ApiApprovalTests.Run.Core3_0.verified.txt index f099611441..42624a065b 100644 --- a/test/Sentry.Tests/ApiApprovalTests.Run.Core3_0.verified.txt +++ b/test/Sentry.Tests/ApiApprovalTests.Run.Core3_0.verified.txt @@ -70,6 +70,19 @@ namespace Sentry public void WriteTo(System.Text.Json.Utf8JsonWriter writer, Sentry.Extensibility.IDiagnosticLogger? logger) { } public static Sentry.Contexts FromJson(System.Text.Json.JsonElement json) { } } + public sealed class DebugImage : Sentry.IJsonSerializable + { + public DebugImage() { } + public string? CodeFile { get; set; } + public string? CodeId { get; set; } + public string? DebugFile { get; set; } + public string? DebugId { get; set; } + public string? ImageAddress { get; set; } + public long? ImageSize { get; set; } + public string? Type { get; set; } + public void WriteTo(System.Text.Json.Utf8JsonWriter writer, Sentry.Extensibility.IDiagnosticLogger? logger) { } + public static Sentry.DebugImage FromJson(System.Text.Json.JsonElement json) { } + } [System.Flags] public enum DeduplicateMode { @@ -362,6 +375,7 @@ namespace Sentry public SentryEvent(System.Exception? exception) { } public System.Collections.Generic.IReadOnlyCollection Breadcrumbs { get; } public Sentry.Contexts Contexts { get; set; } + public System.Collections.Generic.List? DebugImages { get; set; } public string? Environment { get; set; } public Sentry.SentryId EventId { get; } public System.Exception? Exception { get; } @@ -555,6 +569,7 @@ namespace Sentry { public SentryStackFrame() { } public string? AbsolutePath { get; set; } + public string? AddressMode { get; set; } public int? ColumnNumber { get; set; } public string? ContextLine { get; set; } public string? FileName { get; set; } diff --git a/test/Sentry.Tests/ApiApprovalTests.Run.Core3_1.verified.txt b/test/Sentry.Tests/ApiApprovalTests.Run.Core3_1.verified.txt index 5c965ff1ab..a3202bd7e4 100644 --- a/test/Sentry.Tests/ApiApprovalTests.Run.Core3_1.verified.txt +++ b/test/Sentry.Tests/ApiApprovalTests.Run.Core3_1.verified.txt @@ -70,6 +70,19 @@ namespace Sentry public void WriteTo(System.Text.Json.Utf8JsonWriter writer, Sentry.Extensibility.IDiagnosticLogger? logger) { } public static Sentry.Contexts FromJson(System.Text.Json.JsonElement json) { } } + public sealed class DebugImage : Sentry.IJsonSerializable + { + public DebugImage() { } + public string? CodeFile { get; set; } + public string? CodeId { get; set; } + public string? DebugFile { get; set; } + public string? DebugId { get; set; } + public string? ImageAddress { get; set; } + public long? ImageSize { get; set; } + public string? Type { get; set; } + public void WriteTo(System.Text.Json.Utf8JsonWriter writer, Sentry.Extensibility.IDiagnosticLogger? logger) { } + public static Sentry.DebugImage FromJson(System.Text.Json.JsonElement json) { } + } [System.Flags] public enum DeduplicateMode { @@ -362,6 +375,7 @@ namespace Sentry public SentryEvent(System.Exception? exception) { } public System.Collections.Generic.IReadOnlyCollection Breadcrumbs { get; } public Sentry.Contexts Contexts { get; set; } + public System.Collections.Generic.List? DebugImages { get; set; } public string? Environment { get; set; } public Sentry.SentryId EventId { get; } public System.Exception? Exception { get; } @@ -556,6 +570,7 @@ namespace Sentry { public SentryStackFrame() { } public string? AbsolutePath { get; set; } + public string? AddressMode { get; set; } public int? ColumnNumber { get; set; } public string? ContextLine { get; set; } public string? FileName { get; set; } diff --git a/test/Sentry.Tests/ApiApprovalTests.Run.DotNet4_6.verified.txt b/test/Sentry.Tests/ApiApprovalTests.Run.DotNet4_6.verified.txt index d729db9f36..3771d7f046 100644 --- a/test/Sentry.Tests/ApiApprovalTests.Run.DotNet4_6.verified.txt +++ b/test/Sentry.Tests/ApiApprovalTests.Run.DotNet4_6.verified.txt @@ -70,6 +70,19 @@ namespace Sentry public void WriteTo(System.Text.Json.Utf8JsonWriter writer, Sentry.Extensibility.IDiagnosticLogger? logger) { } public static Sentry.Contexts FromJson(System.Text.Json.JsonElement json) { } } + public sealed class DebugImage : Sentry.IJsonSerializable + { + public DebugImage() { } + public string? CodeFile { get; set; } + public string? CodeId { get; set; } + public string? DebugFile { get; set; } + public string? DebugId { get; set; } + public string? ImageAddress { get; set; } + public long? ImageSize { get; set; } + public string? Type { get; set; } + public void WriteTo(System.Text.Json.Utf8JsonWriter writer, Sentry.Extensibility.IDiagnosticLogger? logger) { } + public static Sentry.DebugImage FromJson(System.Text.Json.JsonElement json) { } + } [System.Flags] public enum DeduplicateMode { @@ -361,6 +374,7 @@ namespace Sentry public SentryEvent(System.Exception? exception) { } public System.Collections.Generic.IReadOnlyCollection Breadcrumbs { get; } public Sentry.Contexts Contexts { get; set; } + public System.Collections.Generic.List? DebugImages { get; set; } public string? Environment { get; set; } public Sentry.SentryId EventId { get; } public System.Exception? Exception { get; } @@ -555,6 +569,7 @@ namespace Sentry { public SentryStackFrame() { } public string? AbsolutePath { get; set; } + public string? AddressMode { get; set; } public int? ColumnNumber { get; set; } public string? ContextLine { get; set; } public string? FileName { get; set; } diff --git a/test/Sentry.Tests/ApiApprovalTests.Run.DotNet5_0.verified.txt b/test/Sentry.Tests/ApiApprovalTests.Run.DotNet5_0.verified.txt index 52dfab4018..1cd928a201 100644 --- a/test/Sentry.Tests/ApiApprovalTests.Run.DotNet5_0.verified.txt +++ b/test/Sentry.Tests/ApiApprovalTests.Run.DotNet5_0.verified.txt @@ -70,6 +70,19 @@ namespace Sentry public void WriteTo(System.Text.Json.Utf8JsonWriter writer, Sentry.Extensibility.IDiagnosticLogger? logger) { } public static Sentry.Contexts FromJson(System.Text.Json.JsonElement json) { } } + public sealed class DebugImage : Sentry.IJsonSerializable + { + public DebugImage() { } + public string? CodeFile { get; set; } + public string? CodeId { get; set; } + public string? DebugFile { get; set; } + public string? DebugId { get; set; } + public string? ImageAddress { get; set; } + public long? ImageSize { get; set; } + public string? Type { get; set; } + public void WriteTo(System.Text.Json.Utf8JsonWriter writer, Sentry.Extensibility.IDiagnosticLogger? logger) { } + public static Sentry.DebugImage FromJson(System.Text.Json.JsonElement json) { } + } [System.Flags] public enum DeduplicateMode { @@ -362,6 +375,7 @@ namespace Sentry public SentryEvent(System.Exception? exception) { } public System.Collections.Generic.IReadOnlyCollection Breadcrumbs { get; } public Sentry.Contexts Contexts { get; set; } + public System.Collections.Generic.List? DebugImages { get; set; } public string? Environment { get; set; } public Sentry.SentryId EventId { get; } public System.Exception? Exception { get; } @@ -556,6 +570,7 @@ namespace Sentry { public SentryStackFrame() { } public string? AbsolutePath { get; set; } + public string? AddressMode { get; set; } public int? ColumnNumber { get; set; } public string? ContextLine { get; set; } public string? FileName { get; set; } diff --git a/test/Sentry.Tests/ApiApprovalTests.Run.DotNet6_0.verified.txt b/test/Sentry.Tests/ApiApprovalTests.Run.DotNet6_0.verified.txt index 7d15fad0ba..b1e3816664 100644 --- a/test/Sentry.Tests/ApiApprovalTests.Run.DotNet6_0.verified.txt +++ b/test/Sentry.Tests/ApiApprovalTests.Run.DotNet6_0.verified.txt @@ -70,6 +70,19 @@ namespace Sentry public void WriteTo(System.Text.Json.Utf8JsonWriter writer, Sentry.Extensibility.IDiagnosticLogger? logger) { } public static Sentry.Contexts FromJson(System.Text.Json.JsonElement json) { } } + public sealed class DebugImage : Sentry.IJsonSerializable + { + public DebugImage() { } + public string? CodeFile { get; set; } + public string? CodeId { get; set; } + public string? DebugFile { get; set; } + public string? DebugId { get; set; } + public string? ImageAddress { get; set; } + public long? ImageSize { get; set; } + public string? Type { get; set; } + public void WriteTo(System.Text.Json.Utf8JsonWriter writer, Sentry.Extensibility.IDiagnosticLogger? logger) { } + public static Sentry.DebugImage FromJson(System.Text.Json.JsonElement json) { } + } [System.Flags] public enum DeduplicateMode { @@ -362,6 +375,7 @@ namespace Sentry public SentryEvent(System.Exception? exception) { } public System.Collections.Generic.IReadOnlyCollection Breadcrumbs { get; } public Sentry.Contexts Contexts { get; set; } + public System.Collections.Generic.List? DebugImages { get; set; } public string? Environment { get; set; } public Sentry.SentryId EventId { get; } public System.Exception? Exception { get; } @@ -556,6 +570,7 @@ namespace Sentry { public SentryStackFrame() { } public string? AbsolutePath { get; set; } + public string? AddressMode { get; set; } public int? ColumnNumber { get; set; } public string? ContextLine { get; set; } public string? FileName { get; set; } diff --git a/test/Sentry.Tests/Protocol/DebugImageTests.cs b/test/Sentry.Tests/Protocol/DebugImageTests.cs new file mode 100644 index 0000000000..126d1040b1 --- /dev/null +++ b/test/Sentry.Tests/Protocol/DebugImageTests.cs @@ -0,0 +1,39 @@ +using Sentry.Tests.Helpers; + +namespace Sentry.Tests.Protocol; + +public class DebugImageTests +{ + [Fact] + public void SerializeObject_AllPropertiesSetToNonDefault_SerializesValidObject() + { + var sut = new DebugImage + { + Type = "elf", + ImageAddress = "0xffffffff", + ImageSize = 1234, + DebugId = "900f7d1b868432939de4457478f34720", + DebugFile = "libc.debug", + CodeId = "900f7d1b868432939de4457478f34720", + CodeFile = "libc.so" + }; + + var actual = sut.ToJsonString(); + + Assert.Equal( + "{" + + "\"type\":\"elf\"," + + "\"image_addr\":\"0xffffffff\"," + + "\"image_size\":1234," + + "\"debug_id\":\"900f7d1b868432939de4457478f34720\"," + + "\"debug_file\":\"libc.debug\"," + + "\"code_id\":\"900f7d1b868432939de4457478f34720\"," + + "\"code_file\":\"libc.so\"" + + "}", + actual); + + var parsed = DebugImage.FromJson(Json.Parse(actual)); + + parsed.Should().BeEquivalentTo(sut); + } +} diff --git a/test/Sentry.Tests/Protocol/Exceptions/SentryStackFrameTests.cs b/test/Sentry.Tests/Protocol/Exceptions/SentryStackFrameTests.cs index 8acf106f4f..b43b7d6ce3 100644 --- a/test/Sentry.Tests/Protocol/Exceptions/SentryStackFrameTests.cs +++ b/test/Sentry.Tests/Protocol/Exceptions/SentryStackFrameTests.cs @@ -26,7 +26,8 @@ public void SerializeObject_AllPropertiesSetToNonDefault_SerializesValidObject() ImageAddress = 3, SymbolAddress = 4, InstructionOffset = 5, - InstructionAddress = "0xffffffff" + InstructionAddress = "0xffffffff", + AddressMode = "rel:0" }; var actual = sut.ToJsonString(); @@ -42,8 +43,7 @@ public void SerializeObject_AllPropertiesSetToNonDefault_SerializesValidObject() "\"module\":\"Module\"," + "\"lineno\":1," + "\"colno\":2," + - "\"abs_path\":" + - "\"AbsolutePath\"," + + "\"abs_path\":\"AbsolutePath\"," + "\"context_line\":\"ContextLine\"," + "\"in_app\":true," + "\"package\":\"Package\"," + @@ -51,9 +51,14 @@ public void SerializeObject_AllPropertiesSetToNonDefault_SerializesValidObject() "\"image_addr\":3," + "\"symbol_addr\":4," + "\"instruction_addr\":\"0xffffffff\"," + - "\"instruction_offset\":5" + + "\"instruction_offset\":5," + + "\"addr_mode\":\"rel:0\"" + "}", actual); + + var parsed = SentryStackFrame.FromJson(Json.Parse(actual)); + + parsed.Should().BeEquivalentTo(sut); } [Fact] diff --git a/test/Sentry.Tests/Protocol/SentryEventTests.cs b/test/Sentry.Tests/Protocol/SentryEventTests.cs index 4c4d35f26b..5138147717 100644 --- a/test/Sentry.Tests/Protocol/SentryEventTests.cs +++ b/test/Sentry.Tests/Protocol/SentryEventTests.cs @@ -39,6 +39,10 @@ public void SerializeObject_AllPropertiesSetToNonDefault_SerializesValidObject() SentryThreads = new[] { new SentryThread { Crashed = true } }, ServerName = "server_name", TransactionName = "transaction", + DebugImages = new List() + { + new DebugImage { Type = "wasm", DebugId = "900f7d1b868432939de4457478f34720" } + }, }; sut.Sdk.AddPackage(new Package("name", "version")); @@ -57,6 +61,11 @@ public void SerializeObject_AllPropertiesSetToNonDefault_SerializesValidObject() var actualString = sut.ToJsonString(); + actualString.Should().Contain( + "\"debug_meta\":{\"images\":[" + + "{\"type\":\"wasm\",\"debug_id\":\"900f7d1b868432939de4457478f34720\"}" + + "]}"); + var actual = SentryEvent.FromJson(Json.Parse(actualString)); // Assert