diff --git a/src/Sentry/Extensibility/SentryStackTraceFactory.cs b/src/Sentry/Extensibility/SentryStackTraceFactory.cs index 336470ed6a..8571589202 100644 --- a/src/Sentry/Extensibility/SentryStackTraceFactory.cs +++ b/src/Sentry/Extensibility/SentryStackTraceFactory.cs @@ -33,6 +33,7 @@ public class SentryStackTraceFactory : ISentryStackTraceFactory var stackTrace = exception is null ? new StackTrace(true) : new StackTrace(exception, true); var result = SentryDebugStackTrace.Create(_options, stackTrace, isCurrentStackTrace); + _options.LogDebug("Created SentryDebugStackTrace with {0} frames.", result.Frames.Count); return result.Frames.Count != 0 ? result : null; } } diff --git a/src/Sentry/Internal/SentryDebugStackTrace.cs b/src/Sentry/Internal/SentryDebugStackTrace.cs index 44576bb5e4..f019980c88 100644 --- a/src/Sentry/Internal/SentryDebugStackTrace.cs +++ b/src/Sentry/Internal/SentryDebugStackTrace.cs @@ -16,8 +16,9 @@ internal sealed class SentryDebugStackTrace : SentryStackTrace private readonly SentryOptions _options; // Debug images referenced by frames in this StackTrace - private readonly Dictionary _debugImageIndexByModule = new(); private readonly List _debugImages = new(); + private readonly Dictionary _debugImageIndexByModule = new(); + private const int DebugImageMissing = -1; private bool _debugImagesMerged = false; /* @@ -62,6 +63,7 @@ internal void MergeDebugImagesInto(SentryEvent @event) } _debugImagesMerged = true; + _options.LogDebug("Merging {0} debug images from stacktrace.", _debugImages.Count); if (_debugImages.Count == 0) { return; @@ -156,6 +158,7 @@ private IEnumerable CreateFrames(StackTrace stackTrace, bool i && stackFrame.GetMethod() is { } method && method.DeclaringType?.AssemblyQualifiedName?.StartsWith("Sentry") == true) { + _options.LogDebug("Skipping initial stack frame '{0}'", method.Name); continue; } @@ -209,10 +212,9 @@ private SentryStackFrame InternalCreateFrame(StackFrame stackFrame, bool demangl AttributeReader.TryGetProjectDirectory(method.Module.Assembly, out projectPath); - var moduleIdx = AddDebugImage(method.Module); - if (moduleIdx != null) + if (AddDebugImage(method.Module) is int moduleIdx && moduleIdx != DebugImageMissing) { - frame.AddressMode = SentryDebugStackTrace.GetRelativeAddressMode((int)moduleIdx); + frame.AddressMode = SentryDebugStackTrace.GetRelativeAddressMode(moduleIdx); try { @@ -238,14 +240,15 @@ private SentryStackFrame InternalCreateFrame(StackFrame stackFrame, bool demangl frame.ConfigureAppFrame(_options); - var frameFileName = stackFrame.GetFileName(); - if (projectPath != null && frameFileName?.StartsWith(projectPath, StringComparison.OrdinalIgnoreCase) is true) + if (stackFrame.GetFileName() is { } frameFileName) { - frameFileName = frameFileName.Substring(projectPath.Length); + if (projectPath != null && frameFileName.StartsWith(projectPath, StringComparison.OrdinalIgnoreCase)) + { + frameFileName = frameFileName.Substring(projectPath.Length); + } + frame.FileName = frameFileName; } - frame.FileName = frameFileName; - // stackFrame.HasILOffset() throws NotImplemented on Mono 5.12 var ilOffset = stackFrame.GetILOffset(); if (ilOffset != StackFrame.OFFSET_UNKNOWN) @@ -374,21 +377,21 @@ private static void DemangleLambdaReturnType(SentryStackFrame frame) { return idx; } - idx = _debugImages.Count; var codeFile = module.FullyQualifiedName; if (!File.Exists(codeFile)) { + _options.LogDebug("Skipping DebugImage for module '{0}' because CodeFile wasn't found: '{1}'", + module.Name, codeFile); + _debugImageIndexByModule.Add(id, DebugImageMissing); // don't try to resolve again return null; } using var stream = File.OpenRead(codeFile); var peReader = new PEReader(stream); - var headers = peReader.PEHeaders; - var peHeader = headers.PEHeader; - string? codeId = null; - if (peHeader != null) + var headers = peReader.PEHeaders; + if (headers.PEHeader is { } peHeader) { codeId = string.Format("{0:X8}{1:x}", headers.CoffHeader.TimeDateStamp, peHeader.SizeOfImage); } @@ -423,9 +426,12 @@ private static void DemangleLambdaReturnType(SentryStackFrame frame) // well, we are out of luck :-( if (debugId == null) { + _options.LogDebug("Skipping DebugImage for module '{0}' because DebugId couldn't be determined", module.Name); + _debugImageIndexByModule.Add(id, DebugImageMissing); // don't try to resolve again return null; } + idx = _debugImages.Count; _debugImages.Add(new DebugImage { Type = "pe_dotnet", diff --git a/test/Sentry.Tests/HubTests.cs b/test/Sentry.Tests/HubTests.cs index 0ec84704bb..1d62241c7c 100644 --- a/test/Sentry.Tests/HubTests.cs +++ b/test/Sentry.Tests/HubTests.cs @@ -472,10 +472,10 @@ public async Task CaptureEvent_ActiveTransaction_UnhandledExceptionTransactionEn }); await Verifier.Verify(worker.Envelopes) + .UniqueForRuntimeAndVersion() .IgnoreStandardSentryMembers() .IgnoreMember("Stacktrace") .IgnoreMember(_ => _.Name) - .UniqueForRuntimeAndVersion() .IgnoreInstance(_ => _.DebugFile.Contains("Xunit.SkippableFact")); }