Output the modern C# 7.0+ features in stack traces that looks like the C# source code that generated them rather than IL formatted.
.NET stack traces output the compiler transformed methods; rather than the source code methods, which make them slow to mentally parse and match back to the source code.
The current output was good for C# 1.0; but has become progressively worse since C# 2.0 (iterators, generics) as new features are added to the .NET languages and at C# 7.1 the stack traces are esoteric (see: Problems with current stack traces).
Output the modern C# 7.0+ features in stack traces in an understandable fashion that looks like the C# source code that generated them.
exception.Demystify()
Or instead of Environment.StackTrace
EnhancedStackTrace.Current()
Resolves the stack back to the C# source format of the calls (and is an inspectable list of stack frames)
Calling .ToString()
on the Demystified exception will produce a string stacktrace similar to the following (without the comments):
System.InvalidOperationException: Collection was modified; enumeration operation may not execute.
at bool System.Collections.Generic.List<T>+Enumerator.MoveNextRare()
at IEnumerable<string> Program.Iterator(int startAt)+MoveNext() // Resolved enumerator
at bool System.Linq.Enumerable+SelectEnumerableIterator<TSource, TResult>.MoveNext() // Resolved enumerator
at string string.Join(string separator, IEnumerable<string> values)
at string Program+GenericClass<TSuperType>.GenericMethod<TSubType>(ref TSubType value)
at async Task<string> Program.MethodAsync(int value) // Resolved async
at async Task<string> Program.MethodAsync<TValue>(TValue value) // Resolved async
at string Program.Method(string value)+()=>{} [0] // lambda source + ordinal
at string Program.Method(string value)+()=>{} [1] // lambda source + ordinal
at string Program.RunLambda(Func<string> lambda)
at (string val, bool) Program.Method(string value) // Tuple returning
at ref string Program.RefMethod(in string value)+LocalFuncRefReturn() // ref return local func
at int Program.RefMethod(in string value)+LocalFuncParam(string val) // local function
at string Program.RefMethod(in string value) // in param (readonly ref)
at (string val, bool) static Program()+(string s, bool b)=>{} // tuple return static lambda
at void static Program()+(string s, bool b)=>{} // void static lambda
at void Program.Start((string val, bool) param) // Resolved tuple param
at void Program.Start((string val, bool) param)+LocalFunc1(long l) // void local function
at bool Program.Start((string val, bool) param)+LocalFunc2(bool b1, bool b2) // bool return local function
at string Program.Start()
at void Program()+()=>{} // ctor defined lambda
at void Program(Action action)+(object state)=>{} // ctor defined lambda
at void Program.RunAction(Action<object> lambda, object state)
at new Program(Action action) // constructor
at new Program() // constructor
at void Program.Main(String[] args)
Calling .ToString()
on the same exception would produce the following output
System.InvalidOperationException: Collection was modified; enumeration operation may not execute.
at System.ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumFailedVersion() // ? low value
at System.Collections.Generic.List`1.Enumerator.MoveNextRare()
at Program.<Iterator>d__3.MoveNext() // which enumerator?
at System.Linq.Enumerable.SelectEnumerableIterator`2.MoveNext() // which enumerator?
at System.String.Join(String separator, IEnumerable`1 values)
at Program.GenericClass`1.GenericMethod[TSubType](TSubType& value)
at Program.<MethodAsync>d__4.MoveNext() // which async overload?
--- End of stack trace from previous location where exception was thrown --- // ? no value
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() // ? no value
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) // ? no value
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() // ? no value
at Program.<MethodAsync>d__5`1.MoveNext() // which async overload?
--- End of stack trace from previous location where exception was thrown --- // ? no value
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() // ? no value
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) // ? no value
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() // ? no value
at Program.<>c__DisplayClass8_0.<Method>b__0() // ¯\_(ツ)_/¯
at Program.<>c__DisplayClass8_0.<Method>b__1() // ¯\_(ツ)_/¯
at Program.RunLambda(Func`1 lambda)
at Program.Method(String value)
at Program.<RefMethod>g__LocalFuncRefReturn|10_1(<>c__DisplayClass10_0& ) // local function
at Program.<RefMethod>g__LocalFuncParam|10_0(String val, <>c__DisplayClass10_0& ) // local function
at Program.RefMethod(String value)
at Program.<>c.<.cctor>b__18_1(String s, Boolean b) // ¯\_(ツ)_/¯
at Program.<>c.<.cctor>b__18_0(String s, Boolean b) // ¯\_(ツ)_/¯
at Program.Start(ValueTuple`2 param) // Tuple param?
at Program.<Start>g__LocalFunc1|11_0(Int64 l) // local function
at Program.<Start>g__LocalFunc2|11_1(Boolean b1, Boolean b2) // local function
at Program.Start()
at Program.<>c.<.ctor>b__1_0() // ¯\_(ツ)_/¯
at Program.<>c__DisplayClass2_0.<.ctor>b__0(Object state) // ¯\_(ツ)_/¯
at Program.RunAction(Action`1 lambda, Object state)
at Program..ctor(Action action) // constructor
at Program..ctor() // constructor
at Program.Main(String[] args)
Which is far less helpful, and close to jibberish in places
-
constructors
Does not match code, output as
.ctor
and.cctor
-
parameters
Do not specify qualifier
ref
,out
orin
-
iterators
Cannot determine overload
<Iterator>d__3.MoveNext()
rather thanIterator(int startAt)+MoveNext()
-
Linq
Cannot determine overload
Linq.Enumerable.SelectEnumerableIterator``2.MoveNext()
rather than
Linq.Enumerable+SelectEnumerableIterator<TSource, TResult>.MoveNext()
-
async
Cannot determine overload and no modifier such as
async
<MethodAsync>d__5``1.MoveNext()
rather than
async Task<string> Program.MethodAsync(int value)
Noise!
--- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task) at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
lambdas
Mostly jibberish
<>c__DisplayClass2_0.<.ctor>b__0(Object state)
with a suggestion of where they are declared but no hint if there are multiple overloads of the method.local functions
Mostly jibberish
<RefMethod>g__LocalFuncParam|10_0(String val, <>c__DisplayClass10_0& )
with a suggestion of where they are declared but no hint if there are multiple overloads of the method.generic parameters
Not resolved, only an indication of the number
RunLambda(Func``1 lambda)
rather thanRunLambda(Func<string> lambda)
value tuples
Do not match code, output as
ValueTuple``2 param
rather than(string val, bool) param
primitive types
Do not match code, output as
Int64
,Boolean
,String
rather thanlong
,bool
,string
return types
Skipped entirely from method signature
To run benchmarks from the repository root:
dotnet run -p .\test\Ben.Demystifier.Benchmarks\ -c Release -f netcoreapp2.0 All
Note: we're only kicking off via
netcoreapp2.0
, benchmarks will run for all configured platforms likenet462
.ben.demystifier's People
Forkers
drawaes sharon-lin 07101994 regme dreamsql cdoru gundi73 rgmills joestead stephenpatten llenroc molinch georgeduckett matrixdekoder vrnithinkumar mcroley virajs clairernovotny nickcraver aidmsu sergeyteplyakov aelij alexandersher khellang floyddotnet awesomedotnetcore vivekdhami josetr kirillosenkov spidercat tylerap mrvelic drivenet apkd pengweiqhca muffpotter sethnav senthil-curated-ref eramax citizenfx lhutyra iracding camilohe ownrisk rubenmonteiro faakhir-habib yuzd mitchcapper sashapodgoreanu horusiath zhouzu ykankaya erisonliang wn-forks ppioli xiaomi7732 jay-dev-9 mingyangzhu getsentry ynsszr needle-tools bangush skyhoshi ithanshui enemaerke shanerogers tkolb-recom moayyaed cohero wangronghua kahbazi irac-ding dongfo neos-metaverse geothachankary zverx kdmagz angr1st mjthompson73 mohammed-kamal-dev royzhao7 icxldd nathanielboucher ten-four-analytics david0718 mattjohnsonpint tyler-in funroot-khan-wang protiguous fredatgithub madq savranideal butr stefanegli phougatv nick-strohm zilo555 atakanvargul fairushyn ns11ben.demystifier's Issues
Assembly version is missing build and revision numbers
Version 0.0.43 is missing assembly version. When this assembly is references in csproj, it shows as
<Reference Include="Ben.Demystifier, Version=0.0.0.0, Culture=neutral, PublicKeyToken=a6d206e05440431a, processorArchitecture=MSIL"> <HintPath>..\packages\Ben.Demystifier.0.0.43\lib\net45\Ben.Demystifier.dll</HintPath> </Reference>
Version 0.0.8 shows as
<Reference Include="Ben.Demystifier, Version=0.0.8.0, Culture=neutral, processorArchitecture=MSIL"> <HintPath>..\packages\Ben.Demystifier.0.0.8\lib\net45\Ben.Demystifier.dll</HintPath> </Reference>
While this is not a problem by itself. It does cause breakage in any libraries that depend on Ben.Demystifier.
For example, if codeessentials.Extensions.Logging.Demystifier is installed, it works fine with 0.0.8 ,but loading exception is thrown for 0.0.43 :
Could not load file or assembly 'Ben.Demystifier, Version=0.0.4.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
0.1.2 ToStringDemystified() misses exception detail
Exception ex = null; try { throw new InvalidOperationException("aaa") { Data = { ["bbb"] = "ccc", ["ddd"] = "eee", } }; } catch (Exception e) { ex = e; } var str = ex.ToStringDemystified();
0.1.1 output
System.InvalidOperationException: aaa at void Tests.CommonTests.ExceptionDemistyfierTests.TestDemistifyWithData() in D:/.../Infrastructure.Tests/CommonTests/ExceptionDemistyfierTests.cs:line 47
0.1.2 output
at void Tests.CommonTests.ExceptionDemistyfierTests.TestDemistifyWithData() in D:/.../Infrastructure.Tests/CommonTests/ExceptionDemistyfierTests.cs:line 47
BTW, the corresponding test is broken.
var original = e.ToString(); var stringDemystified = e.ToStringDemystified(); _output.WriteLine("Demystified: "); _output.WriteLine(stringDemystified); _output.WriteLine("Original: "); var afterDemystified = e.ToString(); // <-- here _output.WriteLine(afterDemystified); Assert.Equal(original, afterDemystified);
IndexOutOfRangeException in ILReader.ReadOpCode() line 36
When analyzing a certain exception I'm seeing an exception in ILReader.ReadOpCode() line 36 here:
The instruction is 235.
singleByteOpCode
only contains 225 entries.Stack trace:
> System.Diagnostics.Internal.ILReader.ReadOpCode Line 36 C# Symbols loaded. System.Diagnostics.Internal.ILReader.Read Line 25 C# Symbols loaded. System.Diagnostics.EnhancedStackTrace.TryResolveSourceMethod Line 350 C# Symbols loaded. System.Diagnostics.EnhancedStackTrace.TryResolveGeneratedName Line 289 C# Symbols loaded. System.Diagnostics.EnhancedStackTrace.GetMethodDisplayString Line 122 C# Symbols loaded. System.Diagnostics.EnhancedStackTrace.GetFrames Line 71 C# Symbols loaded. System.Diagnostics.EnhancedStackTrace.EnhancedStackTrace Line 46 C# Symbols loaded.
Strong-Naming the assembly
What are the odds of you strong-naming the assembly anytime soon?
I can get around it by repackaging the nuget, but I would rather use yours directly so I can pull updates easily.
Any plans for .NET Native support (UWP in RELEASE mode)?
Hello Ben, I've started using this lib and I have to say so far it's great, you did an awesome job here!
I did some tests with the UWP framework and it looks like theDemistify
method fails when the app is compiled in RELEASE mode, ie. when the .NET Native toolchain is enabled.Here's a simple screen, you can see both the stack traces are the same (the first one is the original, the second is the one extracted after calling
Demistify
):
Are there any plans to support the .NET Native compiler in the future, and is that possible in the first place?
Cheers!
SergioSystem.Runtime.InteropServices.COMException being very annoying!
Got some hairy service fabric traces that contain a number of COMExceptions.
Unfortunately it looks like the stack trace for this can't be cleaned up.
Here's a subset of the stack trace!
System.Runtime.InteropServices.COMException (0x80071BCD): Exception from HRESULT: 0x80071BCD at System.Fabric.Interop.NativeClient.IFabricServiceManagementClient6.EndResolveServicePartition(IFabricAsyncOperationContext context) at System.Fabric.FabricClient.ServiceManagementClient.ResolveServicePartitionEndWrapper(IFabricAsyncOperationContext context) at System.Fabric.Interop.AsyncCallOutAdapter2`1.Finish(IFabricAsyncOperationContext context, Boolean expectedCompletedSynchronously)
What appears to be happening is that in
EnhancedStackTrace.GetFrames(Exception)
a newStackTrace
is constructed from the exception, but that stack trace is empty. I think this is because the_stackTrace
field is null, whilst the_stackTraceString
field contains the string representation.So at the moment I don't think anything can be easily done, however it may be worth while putting something in the documentation saying that there are some exceptions that can't be cleaned.
Consider removing asp.net middleware frames
Heres a segment of our stack trace. Note our relevant lines (labelled RiskFabricator) have 10 lines of AspNetCore internals in between.
at async Task RiskFabricator.Controllers.GetRiskController.Get(string product, string version, string base64EnquiryId, CancellationToken cancellationToken) in /build/src/RiskFabricator/Controllers/GetRiskController.cs:line 27
at async Task Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeActionMethodAsync()
at async Task Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeNextActionFilterAsync()
at void Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ActionExecutedContext context)
at Task Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
at async Task Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeInnerFilterAsync()
at async Task Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextResourceFilter()
at void Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext context)
at Task Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
at async Task Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeFilterPipelineAsync()
at async Task Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeAsync()
at async Task Microsoft.AspNetCore.Builder.RouterMiddleware.Invoke(HttpContext httpContext)
at async Task RiskFabricator.HeaderExtractionMiddleware.ExtractEmailHashInformationMiddleware.Invoke(HttpContext context) in /build/src/RiskFabricator/HeaderExtractionMiddleware/ExtractEmailHashInformationMiddleware.cs:line 27Make less mysterious.
NuGet dependency mismatch between ValueTuple and framework version
NuGet package adds duplicate references
I would like to use this, but somehow installing the NuGet package adds a lot of duplicate references to my projects for system packages such as
System.Collections
,System.ComponentModel
, etc.Using .NET Framework 4.6.2 in my projects. For example, the
System.Collections
package referenced is:System.Collections, Version=4.0.10.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.2\Facades\System.Collections.dll
Installing the Demystifier NuGet package adds the duplicate reference:
System.Collections, Version=4.0.11.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a C:\Program Files (x86)\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\ref\System.Collections.dll
Anything I can do about that?
Add ValueTask support
else if (type == typeof(TaskAwaiter) || type == typeof(TaskAwaiter<>) || + type == typeof(ValueTaskAwaiter) || + type == typeof(ValueTaskAwaiter<>) || + type == typeof(ConfiguredValueTaskAwaitable.ConfiguredValueTaskAwaiter) || + type == typeof(ConfiguredValueTaskAwaitable<>.ConfiguredValueTaskAwaiter) || type == typeof(ConfiguredTaskAwaitable.ConfiguredTaskAwaiter) || type == typeof(ConfiguredTaskAwaitable<>.ConfiguredTaskAwaiter)) {
<PropertyGroup> - <TargetFrameworks>netstandard2.0;net45</TargetFrameworks> + <TargetFrameworks>netstandard2.1;netstandard2.0;net45</TargetFrameworks> </PropertyGroup> <ItemGroup> + <PackageReference Include="System.Threading.Tasks.Extensions" Version="4.5.2" Condition="'$(TargetFramework)' != 'netstandard2.1'" /> </ItemGroup>
Source file paths from SourceLinked binaries aren't appended
I am demystifying a first-chance exception that happens in Roslyn. Roslyn source-links all their assemblies, so the file paths in the .pdb look like:
/_/src/EditorFeatures/Core.Wpf/Suggestions/SuggestedActionsSource.cs
Unfortunately constructing a new Uri with that string throws:
There are three problems with this:
- An additional first-chance exception is generated as a side-effect of demystifying. In a system that I'm building we have tightly controlled first-chance exceptions (and ironically, this is where I'm using Demystify - to pretty-print first-chance exceptions and categorize them properly). Having an avoidable first-chance exception here is a deal-breaker for us.
- The source code path for this stack frame is lost.
- Since this is happening for every frame with that pattern of source file path, it's a non-trivial perf penalty since the exception is thrown per frame.
I'm thinking if one could avoid constructing a new Uri here and rewrite the code in a different way.
Thanks!
Some stacks cannot be captured because GetMethodDisplayString doesn't handle generic types
HResult=0x80131509 Message=Late bound operations cannot be performed on fields with types for which Type.ContainsGenericParameters is true. Source=System.Private.CoreLib StackTrace: at System.Reflection.RtFieldInfo.InternalGetValue(Object obj, StackCrawlMark& stackMark) at System.Reflection.RtFieldInfo.GetValue(Object obj) at System.Diagnostics.EnhancedStackTrace.GetMethodDisplayString(MethodBase originMethod) in C:\GitHub\Ben.Demystifier\src\Ben.Demystifier\EnhancedStackTrace.Frames.cs:line 142 at System.Diagnostics.EnhancedStackTrace.GetFrames(StackTrace stackTrace) in C:\GitHub\Ben.Demystifier\src\Ben.Demystifier\EnhancedStackTrace.Frames.cs:line 70 at System.Diagnostics.EnhancedStackTrace..ctor(StackTrace stackTrace) in C:\GitHub\Ben.Demystifier\src\Ben.Demystifier\EnhancedStackTrace.cs:line 47 at System.Diagnostics.EnhancedStackTrace.Current() in C:\GitHub\Ben.Demystifier\src\Ben.Demystifier\EnhancedStackTrace.cs:line 14 at Sparrow.NativeAllocator`1.Initialize(NativeAllocator`1& allocator) in F:\ravendb-4.0\src\Sparrow\Allocators.Native.cs:line 106
The real stack trace is:
at System.Environment.get_StackTrace() at System.Reflection.RtFieldInfo.InternalGetValue(Object obj, StackCrawlMark& stackMark) at System.Reflection.RtFieldInfo.GetValue(Object obj) at System.Diagnostics.EnhancedStackTrace.GetMethodDisplayString(MethodBase originMethod) in C:\GitHub\Ben.Demystifier\src\Ben.Demystifier\EnhancedStackTrace.Frames.cs:line 142 at System.Diagnostics.EnhancedStackTrace.GetFrames(StackTrace stackTrace) in C:\GitHub\Ben.Demystifier\src\Ben.Demystifier\EnhancedStackTrace.Frames.cs:line 70 at System.Diagnostics.EnhancedStackTrace..ctor(StackTrace stackTrace) in C:\GitHub\Ben.Demystifier\src\Ben.Demystifier\EnhancedStackTrace.cs:line 47 at System.Diagnostics.EnhancedStackTrace.Current() in C:\GitHub\Ben.Demystifier\src\Ben.Demystifier\EnhancedStackTrace.cs:line 14 at Sparrow.NativeAllocator`1.Initialize(NativeAllocator`1& allocator) in F:\ravendb-4.0\src\Sparrow\Allocators.Native.cs:line 106 at Sparrow.ArenaAllocator`1.Initialize(ArenaAllocator`1& allocator) in F:\ravendb-4.0\src\Sparrow\Allocators.Arena.cs:line 126 at Sparrow.Allocator`1.Initialize[TAllocatorOptions](TAllocatorOptions options) in F:\ravendb-4.0\src\Sparrow\Allocators.cs:line 129 at Sparrow.Json.JsonOperationContext.Renew() in F:\ravendb-4.0\src\Sparrow\Json\JsonOperationContext.cs:line 970 at Sparrow.Json.JsonContextPoolBase`1.TryReuseExistingContextFrom(ContextStack stack, T& context, IDisposable& disposable) in F:\ravendb-4.0\src\Sparrow\Json\JsonContextPoolBase.cs:line 173 at Sparrow.Json.JsonContextPoolBase`1.AllocateOperationContext(T& context) in F:\ravendb-4.0\src\Sparrow\Json\JsonContextPoolBase.cs:line 138 at Sparrow.Json.JsonOperationContext.ManagedPinnedBuffer.Clone[T](JsonContextPoolBase`1 pool) in F:\ravendb-4.0\src\Sparrow\Json\JsonOperationContext.cs:line 215 at Raven.Server.Documents.Replication.IncomingReplicationHandler..ctor(TcpConnectionOptions options, ReplicationLatestEtagRequest replicatedLastEtag, ReplicationLoader parent, ManagedPinnedBuffer bufferToCopy) in F:\ravendb-4.0\src\Raven.Server\Documents\Replication\IncomingReplicationHandler.cs:line 75 at Raven.Server.Documents.Replication.ReplicationLoader.AcceptIncomingConnection(TcpConnectionOptions tcpConnectionOptions, ManagedPinnedBuffer buffer) in F:\ravendb-4.0\src\Raven.Server\Documents\Replication\ReplicationLoader.cs:line 248 at Raven.Server.RavenServer.DispatchDatabaseTcpConnection(TcpConnectionOptions tcp, TcpConnectionHeaderMessage header, ManagedPinnedBuffer bufferToCopy) in F:\ravendb-4.0\src\Raven.Server\RavenServer.cs:line 1469 at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](TStateMachine& stateMachine) at Raven.Server.RavenServer.DispatchDatabaseTcpConnection(TcpConnectionOptions tcp, TcpConnectionHeaderMessage header, ManagedPinnedBuffer bufferToCopy) at Raven.Server.RavenServer.<>c__DisplayClass46_0.<<ListenToNewTcpConnection>b__0>d.MoveNext() in F:\ravendb-4.0\src\Raven.Server\RavenServer.cs:line 1289 at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.MoveNext() at System.Runtime.CompilerServices.TaskAwaiter.<>c.<OutputWaitEtwEvents>b__12_0(Action innerContinuation, Task innerTask) at System.Threading.Tasks.AwaitTaskContinuation.RunOrScheduleAction(Action action, Boolean allowInlining) at System.Threading.Tasks.Task.RunContinuations(Object continuationObject) at System.Threading.Tasks.Task`1.TrySetResult(TResult result) at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.SetExistingTaskResult(TResult result) at Sparrow.Json.JsonOperationContext.ParseToMemoryAsync(Stream stream, String documentId, UsageMode mode, ManagedPinnedBuffer bytes, Nullable`1 token, Int32 maxSize) in F:\ravendb-4.0\src\Sparrow\Json\JsonOperationContext.cs:line 942 at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.MoveNext() at System.Runtime.CompilerServices.TaskAwaiter.<>c.<OutputWaitEtwEvents>b__12_0(Action innerContinuation, Task innerTask) at System.Threading.Tasks.AwaitTaskContinuation.RunOrScheduleAction(Action action, Boolean allowInlining) at System.Threading.Tasks.Task.RunContinuations(Object continuationObject) at System.Threading.Tasks.Task`1.TrySetResult(TResult result) at System.Threading.Tasks.ValueTask`1.ValueTaskSourceAsTask.<>c.<.cctor>b__4_0(Object state) at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.InvokeContinuation(Action`1 continuation, Object state, Boolean forceAsync) at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.OnCompleted(SocketAsyncEventArgs _) at System.Net.Sockets.SocketAsyncEventArgs.FinishOperationAsyncSuccess(Int32 bytesTransferred, SocketFlags flags) at System.Net.Sockets.SocketAsyncEventArgs.<>c.<.cctor>b__177_0(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped) at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)
Path separater is "wrong" on Windows
Maybe this is "as designed", but I noticed that Ben.Demystifier uses forward-slashes for path separators, and not backslashes, as the normal exception stack trace on Windows. It this intentional, for it to be the same across all platforms, or unintentional?
Stack trace for generic types with tuples is incorrect
Here is an example:
async Task<(int left, int right)> AsyncThatReturnsTuple() { await Task.Delay(1).ConfigureAwait(false); throw new ArgumentException(); }
In this case the demystified exception looks like this:
at async (ValueTuple<int, int> left) ConsoleApp11.Program.AsyncWithTuple()
But should be
at async Task<(int left, int right)> ConsoleApp11.Program.AsyncWithTuple()
File names are missing in the stack trace when assemblies are built with /pathmap
If the dll is built with /patmap option (see Deterministic Builds in Roslyn for more details), then the file names in the original stack trace could be a bit weird like this:
\.\Sources\Foo\Bar.cs
.The Demystifier tries to get the full path for such a frame, fails doing that and skips the file name altogether.
Demystify some more esoteric stack traces
Hi!
Is it possible to improve readability of the bold marked lines?
Application startup exception: System.Net.Sockets.SocketException (61): Connection refused
at Npgsql.NpgsqlConnector.Connect(NpgsqlTimeout timeout) in C:\projects\npgsql\src\Npgsql\NpgsqlConnector.cs:line 704
at Npgsql.NpgsqlConnector.RawOpen(NpgsqlTimeout timeout, Boolean async, CancellationToken cancellationToken) in C:\projects\npgsql\src\Npgsql\NpgsqlConnector.cs:line 555
at Npgsql.NpgsqlConnector.Open(NpgsqlTimeout timeout, Boolean async, CancellationToken cancellationToken) in C:\projects\npgsql\src\Npgsql\NpgsqlConnector.cs:line 414
at Npgsql.NpgsqlConnection.<>c__DisplayClass32_0.<g__OpenLong|0>d.MoveNext() in C:\projects\npgsql\src\Npgsql\NpgsqlConnection.cs:line 272
--- End of stack trace from previous location where exception was thrown ---
at Npgsql.NpgsqlConnection.Open() in C:\projects\npgsql\src\Npgsql\NpgsqlConnection.cs:line 153
at Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.NpgsqlDatabaseCreator.Exists() in C:\projects\npgsql-entityframeworkcore-postgresql\src\EFCore.PG\Storage\Internal\NpgsqlDatabaseCreator.cs:line 216
at Microsoft.EntityFrameworkCore.Migrations.HistoryRepository.Exists()
at Microsoft.EntityFrameworkCore.Migrations.Internal.Migrator.Migrate(String targetMigration)
at Microsoft.EntityFrameworkCore.RelationalDatabaseFacadeExtensions.Migrate(DatabaseFacade databaseFacade)
at Sapphire.EntityFrameworkCore.Extensions.ServiceProviderExtensions.MigrateDatabase[TContext](IServiceProvider serviceProvider) in /Users/krisztian.kocsis/Documents/Projects/miw-cloud/modules/sapphire/src/Sapphire.EntityFrameworkCore/Extensions/ServiceProviderExtensions.cs:line 41
at MIW.Cloud.Web.Bootstrap.Configure(IApplicationBuilder applicationBuilder) in /Users/krisztian.kocsis/Documents/Projects/miw-cloud/src/MIW.Cloud.Web/Bootstrap.cs:line 135
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.AspNetCore.Hosting.ConventionBasedStartup.Configure(IApplicationBuilder app)
at Microsoft.AspNetCore.HostFilteringStartupFilter.<>c__DisplayClass0_0.b__0(IApplicationBuilder app)
at Microsoft.AspNetCore.Hosting.Internal.AutoRequestServicesStartupFilter.<>c__DisplayClass0_0.b__0(IApplicationBuilder builder)
at Microsoft.AspNetCore.Hosting.Internal.WebHost.BuildApplication()Local function with method invocation on variable from outer scope
I have discovered erroneous behavior with local function. Here a small app to reproduce:
internal class Program { private static async Task Main(string[] args) { int number = default; try { await Fun(); async Task Fun() { number.ToString(); throw new Exception(); } } catch (Exception e) { Console.WriteLine(e.Demystify()); } }
Execution of the code above produces following stack trace:
System.Exception: Exception of type 'System.Exception' was thrown. at void Program+<>c__DisplayClass0_0+<<Main>g__Fun|0>d.MoveNext() at async Task Program.Main(string[] args)
If I remove
number.ToString();
it produces expected stack trace.Error parsing stack trace (in ILReader.ReadOpCode)
I'm getting the following error in my logs:
IndexOutOfRangeException: Message: Index was outside the bounds of the array. Stack trace: at OpCode System.Diagnostics.Internal.ILReader.ReadOpCode() at bool System.Diagnostics.Internal.ILReader.Read(MethodBase methodInfo) at bool System.Diagnostics.EnhancedStackTrace.TryResolveSourceMethod(IEnumerable<MethodBase> candidateMethods, GeneratedNameKind kind, string matchHint, ref MethodBase method, ref Type type, out Nullable<int> ordinal) at bool System.Diagnostics.EnhancedStackTrace.TryResolveGeneratedName(ref MethodBase method, out Type type, out string methodName, out string subMethodName, out GeneratedNameKind kind, out Nullable<int> ordinal) at ResolvedMethod System.Diagnostics.EnhancedStackTrace.GetMethodDisplayString(MethodBase originMethod) at List<EnhancedStackFrame> System.Diagnostics.EnhancedStackTrace.GetFrames(StackTrace stackTrace) at List<EnhancedStackFrame> System.Diagnostics.EnhancedStackTrace.GetFrames(Exception exception) at new System.Diagnostics.EnhancedStackTrace(Exception e) at new DDS.Runtime.Diagnostics.Data.Details.ExceptionDetailBuilder(Exception exception)
Since I'm catching possible errors in Demystifier, when this happens, I store the original stack trace unmodified, so the above error was related to this stack trace:
Message: Unable to connect to any of the specified MySQL hosts. Stack trace: at MySqlConnector.Core.ServerSession.<ConnectAsync>d__56.MoveNext() in C:\projects\mysqlconnector\src\MySqlConnector\Core\ServerSession.cs:line 215 --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at MySql.Data.MySqlClient.MySqlConnection.<CreateSessionAsync>d__77.MoveNext() in C:\projects\mysqlconnector\src\MySqlConnector\MySql.Data.MySqlClient\MySqlConnection.cs:line 365 --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult() at MySql.Data.MySqlClient.MySqlConnection.<OpenAsync>d__19.MoveNext() in C:\projects\mysqlconnector\src\MySqlConnector\MySql.Data.MySqlClient\MySqlConnection.cs:line 160 --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at MySql.Data.MySqlClient.MySqlConnection.Open() in C:\projects\mysqlconnector\src\MySqlConnector\MySql.Data.MySqlClient\MySqlConnection.cs:line 137 at Microsoft.EntityFrameworkCore.Storage.Internal.MySqlConnectionSettings.<>c__DisplayClass2_0.<GetSettings>b__0(String key) at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory) at Microsoft.EntityFrameworkCore.Storage.Internal.MySqlConnectionSettings.GetSettings(String connectionString) at Microsoft.EntityFrameworkCore.Internal.MySqlOptions.<.ctor>b__2_0() at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode) --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Lazy`1.CreateValue() at Microsoft.EntityFrameworkCore.Internal.MySqlOptions.get_ConnectionSettings() at Microsoft.EntityFrameworkCore.Storage.Internal.MySqlSmartTypeMapper.MaybeConvertMapping(RelationalTypeMapping mapping) at Microsoft.EntityFrameworkCore.Storage.Internal.MySqlSmartTypeMapper.FindMapping(Type clrType) at Microsoft.EntityFrameworkCore.Storage.RelationalTypeMapper.IsTypeMapped(Type clrType) at Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.PropertyDiscoveryConvention.IsCandidatePrimitiveProperty(PropertyInfo propertyInfo) at System.Linq.Enumerable.WhereArrayIterator`1.MoveNext() at Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.PropertyDiscoveryConvention.Apply(InternalEntityTypeBuilder entityTypeBuilder) at Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.ConventionDispatcher.ImmediateConventionScope.OnEntityTypeAdded(InternalEntityTypeBuilder entityTypeBuilder) at Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.ConventionDispatcher.OnEntityTypeAdded(InternalEntityTypeBuilder entityTypeBuilder) at Microsoft.EntityFrameworkCore.Metadata.Internal.Model.AddEntityType(EntityType entityType) at Microsoft.EntityFrameworkCore.Metadata.Internal.Model.AddEntityType(Type type, ConfigurationSource configurationSource) at Microsoft.EntityFrameworkCore.Metadata.Internal.InternalModelBuilder.Entity(TypeIdentity type, ConfigurationSource configurationSource) at Microsoft.EntityFrameworkCore.Metadata.Internal.InternalModelBuilder.Entity(Type type, ConfigurationSource configurationSource) at Microsoft.EntityFrameworkCore.ModelBuilder.Entity(Type type) at Microsoft.EntityFrameworkCore.Infrastructure.ModelCustomizer.FindSets(ModelBuilder modelBuilder, DbContext context) at Microsoft.EntityFrameworkCore.Infrastructure.RelationalModelCustomizer.FindSets(ModelBuilder modelBuilder, DbContext context) at Microsoft.EntityFrameworkCore.Infrastructure.ModelCustomizer.Customize(ModelBuilder modelBuilder, DbContext context) at Microsoft.EntityFrameworkCore.Infrastructure.RelationalModelCustomizer.Customize(ModelBuilder modelBuilder, DbContext context) at Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.CreateModel(DbContext context, IConventionSetBuilder conventionSetBuilder, IModelValidator validator) at Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.<>c__DisplayClass5_0.<GetModel>b__0(Object k) at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory) at Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.GetModel(DbContext context, IConventionSetBuilder conventionSetBuilder, IModelValidator validator) at Microsoft.EntityFrameworkCore.Internal.DbContextServices.CreateModel() at Microsoft.EntityFrameworkCore.Internal.DbContextServices.get_Model() at Microsoft.EntityFrameworkCore.Infrastructure.EntityFrameworkServicesBuilder.<>c.<TryAddCoreServices>b__7_1(IServiceProvider p) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactory(FactoryCallSite factoryCallSite, ServiceProvider provider) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(IServiceCallSite callSite, TArgument argument) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped(ScopedCallSite scopedCallSite, ServiceProvider provider) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(IServiceCallSite callSite, TArgument argument) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, ServiceProvider provider) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(IServiceCallSite callSite, TArgument argument) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped(ScopedCallSite scopedCallSite, ServiceProvider provider) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(IServiceCallSite callSite, TArgument argument) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(IServiceCallSite callSite, ServiceProvider provider) at Microsoft.Extensions.DependencyInjection.ServiceProvider.<>c__DisplayClass22_0.<RealizeService>b__0(ServiceProvider provider) at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Type serviceType) at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetService[T](IServiceProvider provider) at Microsoft.EntityFrameworkCore.Infrastructure.EntityFrameworkServicesBuilder.<>c.<TryAddCoreServices>b__7_10(IServiceProvider p) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactory(FactoryCallSite factoryCallSite, ServiceProvider provider) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(IServiceCallSite callSite, TArgument argument) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped(ScopedCallSite scopedCallSite, ServiceProvider provider) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(IServiceCallSite callSite, TArgument argument) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitIEnumerable(IEnumerableCallSite enumerableCallSite, ServiceProvider provider) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(IServiceCallSite callSite, TArgument argument) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(IServiceCallSite callSite, ServiceProvider provider) at Microsoft.Extensions.DependencyInjection.ServiceProvider.<>c__DisplayClass22_0.<RealizeService>b__0(ServiceProvider provider) at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Type serviceType) at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetService[T](IServiceProvider provider) at Microsoft.EntityFrameworkCore.DbContext.Microsoft.EntityFrameworkCore.Internal.IDbContextPoolable.ResetState() at Microsoft.EntityFrameworkCore.Internal.DbContextPool`1.Return(TContext context) at Microsoft.EntityFrameworkCore.Internal.DbContextPool`1.Microsoft.EntityFrameworkCore.Internal.IDbContextPool.Return(DbContext context) at Microsoft.EntityFrameworkCore.DbContext.Dispose() at Microsoft.Extensions.DependencyInjection.ServiceProvider.Dispose() at Microsoft.AspNetCore.Hosting.Internal.WebHost.Dispose()
GetMethodDisplayString incorrectly decodes nested lambda
I'm using
EnhancedStackTrace.GetMethodDisplayString
on its own to decode the name of a lambda nested in another lambda, but the result is not correct.Specifically, it reproduces with this code:
using System; using System.Diagnostics; class Program { static void Main() { void Execute(Action a) => a(); Execute(() => { Action b = () => {}; Console.WriteLine(EnhancedStackTrace.GetMethodDisplayString(b.Method)); }); } }
This prints
void Program+<>c.<Main>b__0_2(?)+() => { }
, which still looks mystifying.This code decompiles to:
internal class Program { [CompilerGenerated] [Serializable] private sealed class <>c { public static readonly Program.<>c <>9 = new Program.<>c(); public static Action <>9__0_2; public static Action <>9__0_1; internal void <Main>b__0_1() { Action arg_1F_0; if ((arg_1F_0 = Program.<>c.<>9__0_2) == null) { Program.<>c.<>9__0_2 = (arg_1F_0 = new Action(Program.<>c.<>9.<Main>b__0_2)); } Console.WriteLine(EnhancedStackTrace.GetMethodDisplayString(arg_1F_0.Method)); } internal void <Main>b__0_2() { } } private static void Main() { Action arg_1F_0; if ((arg_1F_0 = Program.<>c.<>9__0_1) == null) { Program.<>c.<>9__0_1 = (arg_1F_0 = new Action(Program.<>c.<>9.<Main>b__0_1)); } Program.<Main>g__Execute0_0(arg_1F_0); } [CompilerGenerated] internal static void <Main>g__Execute0_0(Action a) { a(); } }
Does this works with Xamarin Forms?
Does this works with Xamarin Forms?
Support filtering frames
We've hit a scenario where we want to reduce additional noise from framework components to cut down logging costs.
Specific scenario we have is with ASP.NET MVC and ActionFilterAttributes, we have several registered and it results in a fair amount of excessive information in the logs, for example:
at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.CallOnActionExecutedAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation) at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.CallOnActionExecutedAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation) at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.ExecuteActionFilterAsyncCore(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation) at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.CallOnActionExecutedAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation) at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.CallOnActionExecutedAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation) at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.ExecuteActionFilterAsyncCore(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation) at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.CallOnActionExecutedAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation) at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.CallOnActionExecutedAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation) at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.ExecuteActionFilterAsyncCore(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation) at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.CallOnActionExecutedAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation) at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.CallOnActionExecutedAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation) at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.ExecuteActionFilterAsyncCore(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation) at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.CallOnActionExecutedAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation) at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.CallOnActionExecutedAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation) at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.ExecuteActionFilterAsyncCore(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation) at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.CallOnActionExecutedAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation) at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.CallOnActionExecutedAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation) at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.ExecuteActionFilterAsyncCore(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation) at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.CallOnActionExecutedAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation) at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.CallOnActionExecutedAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation) at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.ExecuteActionFilterAsyncCore(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation) at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.CallOnActionExecutedAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation) at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.CallOnActionExecutedAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation) at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.ExecuteActionFilterAsyncCore(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation) at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.CallOnActionExecutedAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation) at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.CallOnActionExecutedAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation) at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.ExecuteActionFilterAsyncCore(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation) at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.CallOnActionExecutedAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation) at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.CallOnActionExecutedAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation) at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.ExecuteActionFilterAsyncCore(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation) at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.CallOnActionExecutedAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation) at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.CallOnActionExecutedAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation) at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.ExecuteActionFilterAsyncCore(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation) at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.CallOnActionExecutedAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation) at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.CallOnActionExecutedAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation) at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.ExecuteActionFilterAsyncCore(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation) at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.CallOnActionExecutedAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation) at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.CallOnActionExecutedAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation) at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.ExecuteActionFilterAsyncCore(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation) at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.CallOnActionExecutedAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation) at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.CallOnActionExecutedAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation) at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.ExecuteActionFilterAsyncCore(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
This is included in any stack trace as from our API and represents about 75% of the stacktrace itself. Do you think there would be value in supporting some filtering mechanism to allow consumers to reduce the output?
Could not load file or assembly 'Ben.Demystifier, Version=0.1.0.0 ...
Attempting to use
Ben.Demystifier
version 0.1.4 installed via NuGet. I am getting the following error at runtime.Looks like the version number is not getting set correctly?
Could not load file or assembly 'Ben.Demystifier, Version=0.1.0.0, Culture=neutral, PublicKeyToken=a6d206e05440431a' or one of its dependencies. The system cannot find the file specified.
Error: Index was outside the bounds of the array.
I just saw this on my logs:
23-11-2017 19:49:53:782: [Error ] ProcessRequestAsync IndexOutOfRangeException: Message: Index was outside the bounds of the array. Stack trace: at ParameterInfo Attribute.GetParentDefinition(ParameterInfo param) at Attribute[] Attribute.InternalParamGetCustomAttributes(ParameterInfo param, Type type, bool inherit) at IEnumerable<T> System.Reflection.CustomAttributeExtensions.GetCustomAttributes<T>(ParameterInfo element) at ResolvedParameter System.Diagnostics.EnhancedStackTrace.GetParameter(ParameterInfo parameter) at ResolvedMethod System.Diagnostics.EnhancedStackTrace.GetMethodDisplayString(MethodBase originMethod) at List<EnhancedStackFrame> System.Diagnostics.EnhancedStackTrace.GetFrames(StackTrace stackTrace) at List<EnhancedStackFrame> System.Diagnostics.EnhancedStackTrace.GetFrames(Exception exception) at new System.Diagnostics.EnhancedStackTrace(Exception e) at new DDS.Runtime.Diagnostics.Data.Details.ExceptionDetailBuilder(Exception exception) at ILogEntry DDS.Runtime.Diagnostics.Logger.Write(LogEventType eventType, string message, Exception exception, LogEntryData data) at ILogEntry DDS.Runtime.Diagnostics.Primitives.DiagnosticsPrimitivesExtensions.LogError(ILogger logger, Exception exception, LogEntryData data) at void DDS.AspNetCore.Mvc.Filters.StatusExceptionFilter.OnException(ExceptionContext context) at Task Microsoft.AspNetCore.Mvc.Filters.ExceptionFilterAttribute.OnExceptionAsync(ExceptionContext context) at Task Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted) at async Task Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextResourceFilter() at void Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext context) at Task Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted) at async Task Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeFilterPipelineAsync() at async Task Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeAsync() at async Task Microsoft.AspNetCore.Builder.RouterMiddleware.Invoke(HttpContext httpContext) at async Task Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext context) at async Task Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext context) at async Task Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context) at async Task Microsoft.AspNetCore.ResponseCompression.ResponseCompressionMiddleware.Invoke(HttpContext context) at async Task Microsoft.AspNetCore.Hosting.Internal.RequestServicesContainerMiddleware.Invoke(HttpContext httpContext) at async void Microsoft.AspNetCore.Server.HttpSys.MessagePump.ProcessRequestAsync(object requestContextObj) at async void Microsoft.AspNetCore.Server.HttpSys.MessagePump.ProcessRequestAsync(object requestContextObj)
Not sure what the original error was.... I'm trying to reproduce locally and post any additional information...
Expose cleaned up Exception
Right now when an exception is
.Demystify()
it exposes a cleaned up stack trace.
The issue is, I'm using Bugsnag (probably not the only library) that takes the exception and builds some internal structure (StackTraceLine - https://github.com/bugsnag/bugsnag-dotnet/blob/96360fb0f8d31f5fd6a8f3f17184bd626421820e/src/Bugsnag/Payload/Exception.cs#L85) before logging it. Therefore, the Demystifier has no effect.Can we please get a
Demystify()
that cleans up the stack frames as well so that if the exception is used in another library it will not include the unnecessary stack frames?.Net4.0 Support
Hi,
It would be great if this package target .net4.0 as it is the last Long Term release and heavily deployed. Also, it would be great if Demystifier can work in StackTrace string as that would really much increase its usability even in CI Servers to post-process data.Thanks for this great package
Assemblies in NuGet package are not signed with Authenticode
Is it possible to sign the assemblies with Authenticode ?
C:\Program Files (x86)\Windows Kits\10\bin\10.0.17763.0\x64>signtool verify "C:\Users\sezhezhe\.nuget\packages\ben.demystifier\0.1.4\lib\netstandard2.0\Ben.Demystifier.dll" File: C:\Users\sezhezhe\.nuget\packages\ben.demystifier\0.1.4\lib\netstandard2.0\Ben.Demystifier.dll Index Algorithm Timestamp ======================================== SignTool Error: No signature found. Number of errors: 1
- @onovotny who helped with strong-name signing for this project and maintains https://github.com/dotnet/SignService.
ToStringDemystified() doesn't use the standard ToString() pattern for inner exceptions
Consider the following LINQPad code:
void Main() { try { Foo(); } catch (Exception e) { e.ToString().Dump("ToString"); e.ToStringDemystified().Dump("ToStringDemystified"); e.Demystify().ToString().Dump(".Demystify().ToString()"); } } public void Foo() { try { Bar();} catch(Exception e) {throw new InvalidOperationException("Something failed while trying to Bar", e);} } public void Bar() { try { Baz(); } catch (Exception e) { throw new InvalidOperationException("Something failed while trying to Baz", e); } } public void Baz() { throw new InvalidOperationException("Something went wrong in here"); }
Output for .Demystify().ToString() looks like this:
System.InvalidOperationException: Something failed while trying to Bar ---> System.InvalidOperationException: Something failed while trying to Baz ---> System.InvalidOperationException: Something went wrong in here at void UserQuery.Bar() in C:/Users/james.jensen/AppData/Local/Temp/LINQPad5/_pwdvguda/query_wparci.cs:line 47 --- End of inner exception stack trace --- at void UserQuery.Bar() in C:/Users/james.jensen/AppData/Local/Temp/LINQPad5/_pwdvguda/query_wparci.cs:line 47 at void UserQuery.Foo() in C:/Users/james.jensen/AppData/Local/Temp/LINQPad5/_pwdvguda/query_wparci.cs:line 43 --- End of inner exception stack trace --- at void UserQuery.Foo() in C:/Users/james.jensen/AppData/Local/Temp/LINQPad5/_pwdvguda/query_wparci.cs:line 43 at void UserQuery.Main() in C:/Users/james.jensen/AppData/Local/Temp/LINQPad5/_pwdvguda/query_wparci.cs:line 31
Output for
.ToStringDemystified()
looks like this:System.InvalidOperationException: Something failed while trying to Bar at void UserQuery.Foo() in C:/Users/james.jensen/AppData/Local/Temp/LINQPad5/_pwdvguda/query_wparci.cs:line 43 at void UserQuery.Main() in C:/Users/james.jensen/AppData/Local/Temp/LINQPad5/_pwdvguda/query_wparci.cs:line 31 ---> System.InvalidOperationException: Something failed while trying to Baz at void UserQuery.Bar() in C:/Users/james.jensen/AppData/Local/Temp/LINQPad5/_pwdvguda/query_wparci.cs:line 47 at void UserQuery.Foo() in C:/Users/james.jensen/AppData/Local/Temp/LINQPad5/_pwdvguda/query_wparci.cs:line 43 ---> System.InvalidOperationException: Something went wrong in here at void UserQuery.Bar() in C:/Users/james.jensen/AppData/Local/Temp/LINQPad5/_pwdvguda/query_wparci.cs:line 47 --- End of inner exception stack trace --- --- End of inner exception stack trace ---
I believe this changed in a recent patch version update. (Tested on 0.1.4)
Some System.Web.Mvc DisplayName methods unresolved
I have a stacktrace line that, after prettifying looks like this:
at void System.Web.Mvc.Async.AsyncControllerActionInvoker+<>c__DisplayClass21+<>c__DisplayClass2b.<BeginInvokeAction>b__1c(?)+()=>{}
It looks like it can't find a pdb file for System.Web.Mvc, which resides in the Temporary ASP.NET directory. Could that have something to do with it (and is there anything I can do to make the/a pdb available)?
Is this expected output or could this be prettified further?
Missing Assemblies because of System.ValueTuple?
Probably not a bug, but maybe a good thing to put in readme?
I installed this on a net 461 project yesterday. We ran into weird problems, for example a referenced project couldnt find System.Net.Http 4.2.0.0.I thought maybe net462 was needed so we tried to upgrade. Still the asme problem.
Tried to Run Add-BindingRedirect etc.
Tried upgrading all the way to net471.Never got it to run. If I removed Ben.Demystifier it all worked again.
Any clues on how to resolve this?
Support .NET 4.5
The nugget package target .NET4.6 which mean we can't use it on our .NET4.5 projects.
Thanks you for the greatness !!Aggregate exceptions
Great library! Biggest problem with doing good work is people raise awkward questions! Sorry.
What's the best way to handle AggregateExceptions? I'm using Service Fabric and Serilog for all my logging. Lots of cross service exceptions are exposed as AggregateExceptions and they still produce a generally old fashioned stack trace.
I've got something working by just logging the inner exception, but that seems like I'm handling the problem at the wrong level. I think Demystify should handle the aggregate exception internally.
This change in Demystify may work - does it make sense?
if (exception is AggregateException aex) { foreach (var innerException in aex.InnerExceptions) { innerException.Demystify(); } } else { exception.InnerException?.Demystify(); }
async lambda not Demystified
Throwing from async lambda like so
namespace SomeNamespace { public static class SomeClass { public static void ThrowsSomethingAsync() { Func<Task> f = async () => throw new Exception("Some exception"); f().ConfigureAwait(false).GetAwaiter().GetResult(); } } }
Transforms
at SomeNamespace.SomeClass.<>c.<<ThrowsSomethingAsync>b__0_0>d.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.ConfiguredTaskAwaitable.ConfiguredTaskAwaiter.GetResult() at SomeNamespace.SomeClass.ThrowsSomethingAsync()
into
at void SomeNamespace.SomeClass+<>c+<<ThrowsSomethingAsync>b__0_0>d.MoveNext() at void SomeNamespace.SomeClass.ThrowsSomethingAsync()
without
async
I getat void SomeNamespace.SomeClass.ThrowsSomethingAsync()+() => { } at void SomeNamespace.SomeClass.ThrowsSomethingAsync()
Fails when method does not have ReturnParameter
When there is a dynamically compiled lambda expression in the path, the Demystifier fails on https://github.com/benaadams/Ben.Demystifier/blob/master/src/Ben.Demystifier/EnhancedStackTrace.Frames.cs#L162
Because the
lambda_method
hasnull
in theReturnParameter
(I don't know why) andGetParameter
method fails on that withNullReferenceException
.EnhancedStackTrace fails on exceptions without stack trace
When I have an exception that was not thrown, it does not have any stack trace (
null
is inStackTrace
) andEnhancedStackTrace
fails on that. It kind of makes sense, as there is no stack trace, but I think it would be nicer if would return an empty list or propagate the null.The problem is that this error check returns null from GetFrames and later it throws NullReferenceException on all places that touch
_frames
. I think that it would better to return an empty list in these cases.Support for html/custom formatting
Hi,
This library is great for improving a raw stacktrace (thanks!). I'd love to be able to easily format its output for display on a web page or email too, without having to resort to Regex or parsing the string output.
Looking at the various
Append
methods it looks like this should be possible, however I'm not quite sure what an API would look like, or whether this request belongs within this library at all.My first thought would be creating equivalent methods to the
Append
ones that returned an enumerable token list (consisting of string and token type) rather than appending to aStringBuilder
. The consumer could then iterate over the list inserting formatting sections between the strings as appropriate. Another option could be simply surrounding relevant output with<span>
tags, however this would be pretty inflexible and would have to handle html encoding. An 3rd option could be creating a FormatSettings class that defines various strings to insert before/after certain tokens.Would be great to hear any thoughts on the above.
Use SourceLink when producing Ben.Demystifier.dll
For debugging the Demystifier.dll itself it would be super useful if the file paths in the .pdb pointed to GitHub so that VS debugger could automatically download sources from GitHub (instead of having paths like
C:\GitHub\Ben.Demystifier...
).See here for more details:
https://github.com/ctaggart/SourceLinksrc folder included into nuget package
Is there any particular reason why src folder is included into the nuget package?
Why is Sample in language version 7.2?
Hello
Just a question. Why is sample project in language version 7.2? This is super last version and I am not sure who really has it. Probably most of the people will not compile it. The only place which is needed by 7.2 version is
static string RefMethod(in string value)
.The PDB reader occasionally fails with file access exception
System.IO.IOException: The process cannot access the file 'C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\root\6dac5fe0\f282cd8a\assembly\dl3\5032d4d4\5885728e_c5e2d301\WebApp.Compiled.pdb' because it is being used by another process. void System.IO.__Error.WinIOError(int errorCode, string maybeFullPath) void System.IO.FileStream.Init(string path, FileMode mode, FileAccess access, int rights, bool useRights, FileShare share, int bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, string msgPath, bool bFromProxy, bool useLongPath, bool checkHost) new System.IO.FileStream(string path, FileMode mode, FileAccess access, FileShare share) bool System.Diagnostics.Internal.PortablePdbReader.IsPortable(string pdbPath) MetadataReader System.Diagnostics.Internal.PortablePdbReader.GetMetadataReader(string assemblyPath) void System.Diagnostics.Internal.PortablePdbReader.PopulateStackFrame(StackFrame frameInfo, MethodBase method, int IlOffset, out string fileName, out int row, out int column) List<EnhancedStackFrame> System.Diagnostics.EnhancedStackTrace.GetFrames(StackTrace stackTrace) new System.Diagnostics.EnhancedStackTrace(StackTrace stackTrace) ...
I checked the code for PortablePdbReader and it seems that it opens the files with proper sharing mode (via
File.OpenRead
), so I have no idea why it can fail or who else could be opening the PDB (this is an ASP.NET 4.5 application running in IIS 8), but I believe I still have to report this.
I'm going to place an IOException handler around calls to the Demystifier methods in our code to handle cases like these, and I think you could consider doing the same.Add extension to demystify StackTrace
In some cases we're logging stack traces using
new StackTrace()
and it would be nice to have an extension that would demystify theStackTrace
alone. For now I've hacked it internally by usingnew EnhancedStackTrace(new StackTrace())
but maybe such extension method would be useful for others as well? If you think it's a good idea I can prepare a PR for it.Incorrect paths are constructed for source locations when compiled on Windows but run on !Windows
When running a program that I compiled on Windows (standalone .NET Core app, compiled via
dotnet publish -o foo -c Release -r ubuntu16.04-arm
for a RPi), I get demystified stack traces that have the absolute Windows paths from the PDBs appended to the current working directory of the app on Linux:System.FormatException: Input string was not in a correct format. at float Number.ParseSingle(string value, NumberStyles options, NumberFormatInfo numfmt) at BellowsRecord ZigBeeGrapher.Program+BellowsRecord.Parse(string line) in /home/pi/zigbee-grapher/C:\Users\BojanRajkovic\source\repos\ZigBeeGrapher\Program.cs:line 351 at async Task ZigBeeGrapher.Program.ProcessCsvLinesAsync(IList<string> csvLines) in /home/pi/zigbee-grapher/C:\Users\BojanRajkovic\source\repos\ZigBeeGrapher\Program.cs:line 90
I haven't explored a whole ton, but I suspect there's some absolute path detection that isn't considering this scenario.
Edit: Looks like this code is the culprit: https://github.com/benaadams/Ben.Demystifier/blob/master/src/Ben.Demystifier/EnhancedStackTrace.cs#L110.
GetParameter throws on Task<object> on GetCustomAttributes<TupleElementNamesAttribute>
var tupleNames = parameter.GetCustomAttributes<TupleElementNamesAttribute>().FirstOrDefault()?.TransformNames;
Throws an index of out range exception when there are no custom attributes.
Specific type where I saw it was
System.Threading.Tasks.Task`1[[System.Object, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
Running on .NET 4.6.2
The `EnhancedStackTrace.ShowInStackTrace` probably should cache its results
Hello.
I would like to propose that EnhancedStackTrace.ShowInStackTrace should cache its execution results, because since
Type.GetCustomAttributesData
throwsNotImplementedException
, theShowInStackTrace
method can quickly become a performance bottleneck when used often (at least ifnetstandard20
andnet471
code are mixed in the same domain).Demystify is still run twice on InnerException of an AggregateException
When an
AggregateException
is found,Demystify
is run twice in theInnerException
. The problematic source code can be seen here inExceptionExtensions.cs
.According to the source, the
InnerException
is always the first of theInnerExceptions
. You can find the code in lines 77 and 150.Full type name for method parameters
Type name for a method parameter should include the corresponding namespace if the type is a non-BCL type.
Example:
namespace n { class t { public void m(object p0, n1.t1 p1) => m(null, null as n2.t1); public void m(object p0, n2.t1 p1) => throw new Exception(); } } namespace n1 { class t1 { } } namespace n2 { class t1 { } } new n.t().m(null, null as n1.t1)
Current behavior
void n.t.m(object p0, t1 p1) void n.t.m(object p0, t1 p1)
Expected behavior:
void n.t.m(object p0, n2.t1 p1) void n.t.m(object p0, n1.t1 p1)
DLL in NuGet package is not strong-name signed.
Please add signing support in project file to allow loading dll from other strong-name signed projects.
Add source to the repo
Please provide the source in this repository. Looking at the readme, this thing would be really valuable to already use. Good stuff building this 🥇 .
I can imagine that this is still very much in flux, and rough around the edges, but this thing would already be a great help to understand some weird stacktraces that I see every day. So I would be fine with something that not really finished yet (I'll get it to work).
If there could be a way for already using this, I'd greatly appreciate it. 🎉
Make it a source-only Nuget package
And I'll be happy to use it everywhere.....!
Not compatible with Microsoft.CodeAnalysis.Csharp
First of all thanks a lot, it's very useful to have relevant StackTraces.
Unfortunately I am one of these poor guy that needs to use strongnames. So we used strongnamer which works perfectly. However once you strongname you really need similar versions.
Ben.Demystifier requires System.Reflection.Metadata 1.5.0, which requires System.Collections.Immutable 1.4.0
We also use Microsoft.CodeAnalysis.Csharp, but unfortunately it uses Microsoft.CodeAnalysis.Common 2.4.0, which uses System.Collections.Immutable 1.3.1
So when running the runtime is obviously unhappy.
Do you see a way to make both cohabit?Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
Jobs
Jooble