From c73f507b6c0ff45611c808033af47333a55cf1f3 Mon Sep 17 00:00:00 2001 From: Sergey Tepliakov Date: Wed, 21 Feb 2018 20:27:32 -0800 Subject: [PATCH] More robust absolute path computation for the enhanced stack traces. Fix for #61 --- src/Ben.Demystifier/EnhancedStackTrace.cs | 43 ++++++++++++------- .../EnhancedStackTraceTests.cs | 31 +++++++++++++ 2 files changed, 58 insertions(+), 16 deletions(-) create mode 100644 test/Ben.Demystifier.Test/EnhancedStackTraceTests.cs diff --git a/src/Ben.Demystifier/EnhancedStackTrace.cs b/src/Ben.Demystifier/EnhancedStackTrace.cs index 181bfef..d93b014 100644 --- a/src/Ben.Demystifier/EnhancedStackTrace.cs +++ b/src/Ben.Demystifier/EnhancedStackTrace.cs @@ -1,9 +1,10 @@ -// Copyright (c) Ben A Adams. All rights reserved. +// Copyright (c) Ben A Adams. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Collections; using System.Collections.Generic; using System.Collections.Generic.Enumerable; +using System.IO; using System.Text; namespace System.Diagnostics @@ -104,21 +105,9 @@ namespace System.Diagnostics var filePath = frame.GetFileName(); if (!string.IsNullOrEmpty(filePath)) { - try - { - sb.Append(" in "); - var uri = new Uri(filePath); - if (uri.IsFile) - { - sb.Append(System.IO.Path.GetFullPath(filePath)); - } - else - { - sb.Append(uri); - } - } - catch - { } + sb.Append(" in "); + sb.Append(TryGetFullPath(filePath)); + } var lineNo = frame.GetFileLineNumber(); @@ -133,5 +122,27 @@ namespace System.Diagnostics EnumerableIList GetEnumerator() => EnumerableIList.Create(_frames); IEnumerator IEnumerable.GetEnumerator() => _frames.GetEnumerator(); IEnumerator IEnumerable.GetEnumerator() => _frames.GetEnumerator(); + + /// + /// Tries to convert a given to a full path. + /// Returns original value if the conversion isn't possible or a given path is relative. + /// + public static string TryGetFullPath(string filePath) + { + try + { + var uri = new Uri(filePath); + if (uri.IsFile) + { + return uri.AbsolutePath; + } + + return uri.ToString(); + } + catch (ArgumentException) { } + catch (UriFormatException) { } + + return filePath; + } } } diff --git a/test/Ben.Demystifier.Test/EnhancedStackTraceTests.cs b/test/Ben.Demystifier.Test/EnhancedStackTraceTests.cs new file mode 100644 index 0000000..c00acc9 --- /dev/null +++ b/test/Ben.Demystifier.Test/EnhancedStackTraceTests.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Text; +using Xunit; + +namespace Ben.Demystifier.Test +{ + public class EnhancedStackTraceTests + { + [Theory] + [InlineData(@"file://Sources\MySolution\Foo.cs", @"/MySolution/Foo.cs")] + [InlineData(@"d:\Public\Src\Foo.cs", @"d:/Public/Src/Foo.cs")] + // To be deterministic, the C# compiler can take a /pathmap command line option. + // This option force the compiler to emit the same bits even when their built from the + // differrent locations. + // The binaries built with the pathmap usually don't have an absolute path, + // but have some prefix like \.\. + // This test case makes sure that EhancedStackTrace can deal with such kind of paths. + [InlineData(@"\.\Public\Src\Foo.cs", @"/./Public/Src/Foo.cs")] + public void RelativePathIsConvertedToAnAbsolutePath(string original, string expected) + { + var converted = EnhancedStackTrace.TryGetFullPath(original); + Assert.Equal(expected, NormalizePath(converted)); + } + + // Used in tests to avoid platform-specific issues. + private static string NormalizePath(string path) + => path.Replace("\\", "/"); + } +}