diff --git a/.nuget/BuildCommon.targets b/.nuget/BuildCommon.targets
index fcb1880..09059bc 100644
--- a/.nuget/BuildCommon.targets
+++ b/.nuget/BuildCommon.targets
@@ -19,24 +19,12 @@
TARGET_NET_20
TARGET_NET_40
+ SILVERLIGHT
$(DefineConstants);
$(DefineConstants)$(CustomConstants)
-
-
- $(ProjectDir)$(ProjectName).nuspec
- true
-
- $(BuildDependsOn);
- BuildPackage;
-
-
-
-
diff --git a/ProductionStackTrace.Analyze.Console/ProductionStackTrace.Analyze.Console.csproj b/ProductionStackTrace.Analyze.Console/ProductionStackTrace.Analyze.Console.csproj
index 1386d81..ab83e9c 100644
--- a/ProductionStackTrace.Analyze.Console/ProductionStackTrace.Analyze.Console.csproj
+++ b/ProductionStackTrace.Analyze.Console/ProductionStackTrace.Analyze.Console.csproj
@@ -67,8 +67,12 @@
-->
+
+ $(ProjectDir)$(ProjectName).nuspec
+
+
\ No newline at end of file
diff --git a/ProductionStackTrace.Analyze/ExceptionReportInterpreter.cs b/ProductionStackTrace.Analyze/ExceptionReportInterpreter.cs
index 7395f8e..6d5bab6 100644
--- a/ProductionStackTrace.Analyze/ExceptionReportInterpreter.cs
+++ b/ProductionStackTrace.Analyze/ExceptionReportInterpreter.cs
@@ -30,7 +30,7 @@ public class ExceptionReportInterpreter
// MODULE: AssemblyName => AssemblyFullyQualifiedName; G:27657a27fg376787d6; A:1
private static readonly Regex s_regexAssemblyMapping =
- new Regex(@"MODULE: (?[^\s]+(?=\s+\=>))\s+\=>\s+(?[^;]+)(;\s+(?[a-z]+\:[^;]+))+", RegexOptions.Singleline | RegexOptions.CultureInvariant | RegexOptions.IgnoreCase);
+ new Regex(@"MODULE: (?[^\s]+(?=\s+\=>))\s+\=>\s+(?[^;]+)(;(\s+)?(?[a-z]+\:[^;]+)?)+", RegexOptions.Singleline | RegexOptions.CultureInvariant | RegexOptions.IgnoreCase);
private SymbolSearch _symSearch;
@@ -101,6 +101,13 @@ public void Translate(TextReader r, TextWriter w)
info.Attributes[kv[0]] = kv[1];
}
+ // PDB filename is derived from assembly name + '.pdb' extension
+
+ var assemblyFileName = info.FullyQualifiedName;
+ int idxShortNameEnd = assemblyFileName.IndexOf(',');
+ if (idxShortNameEnd > 0) assemblyFileName = assemblyFileName.Substring(0, idxShortNameEnd);
+ var pdbFileName = assemblyFileName + ".pdb";
+
// If GUID and Age are specified, that means that assembly has debug information
// and the correspodning PDB file would have the matching GUID + Age attributes
@@ -117,21 +124,25 @@ public void Translate(TextReader r, TextWriter w)
info.PdbGuid = pdbGuid;
info.fPdbSpecified = true;
- // PDB filename is derived from assembly name + '.pdb' extension
-
- var assemblyFileName = info.FullyQualifiedName;
- int idxShortNameEnd = assemblyFileName.IndexOf(',');
- if (idxShortNameEnd > 0) assemblyFileName = assemblyFileName.Substring(0, idxShortNameEnd);
-
// Lookup PDB file using configured Symbol Search Paths. If found, then
// load PDB symbol information - it will be used below to find source line numbers
- info.PdbPath = _symSearch.FindPdbFile(assemblyFileName + ".pdb", info.PdbGuid, info.PdbAge);
- if (info.PdbPath != null)
- info.PdbSymbolLoader = SymbolLoader.Load(info.PdbPath);
+ info.PdbPath = _symSearch.FindPdbFile(pdbFileName, info.PdbGuid, info.PdbAge);
+ }
+ }
+ else
+ {
+ // try to search for it anyway
+ info.PdbPath = _symSearch.FindPdbFile(pdbFileName);
+ if (info.PdbPath != null)
+ {
+ info.fPdbSpecified = true;
}
}
+ if (info.PdbPath != null)
+ info.PdbSymbolLoader = SymbolLoader.Load(info.PdbPath);
+
mapping[assemblyName] = info;
}
}
diff --git a/ProductionStackTrace.Analyze/ProductionStackTrace.Analyze.csproj b/ProductionStackTrace.Analyze/ProductionStackTrace.Analyze.csproj
index fcf38cc..d17da2a 100644
--- a/ProductionStackTrace.Analyze/ProductionStackTrace.Analyze.csproj
+++ b/ProductionStackTrace.Analyze/ProductionStackTrace.Analyze.csproj
@@ -34,7 +34,7 @@
..\Lib\dia2lib\net40\dia2lib.dll
- True
+ False
..\Lib\dia2lib\net20\dia2lib.dll
@@ -66,6 +66,9 @@
-->
+
+ $(ProjectDir)$(ProjectName).nuspec
+
@@ -86,5 +89,6 @@
+
\ No newline at end of file
diff --git a/ProductionStackTrace.Analyze/SymbolSearch.cs b/ProductionStackTrace.Analyze/SymbolSearch.cs
index 4ca51f1..fce44df 100644
--- a/ProductionStackTrace.Analyze/SymbolSearch.cs
+++ b/ProductionStackTrace.Analyze/SymbolSearch.cs
@@ -1,5 +1,7 @@
-using System;
+using Dia2Lib;
+using System;
using System.Collections.Generic;
+using System.IO;
using System.Runtime.InteropServices;
using System.Text;
@@ -116,5 +118,32 @@ public string FindPdbFile(string pdbFileName, Guid guid, int age)
return filePath.ToString();
}
+
+ ///
+ /// Looks through the configured symbol paths to find a PDB symbol
+ /// file matching specified name.
+ ///
+ /// Name of the PDB file.
+ /// The pdb file path or null the pdf file wasn't found.
+ public string FindPdbFile(string pdbFileName)
+ {
+ foreach (string symbolPath in this.SymbolPaths)
+ {
+ string filePath = Path.Combine(symbolPath, pdbFileName);
+ if (File.Exists(filePath))
+ {
+ DiaSourceClass dia = new DiaSourceClass();
+ dia.loadDataFromPdb(filePath);
+ IDiaSession session;
+ dia.openSession(out session);
+
+ IDiaSymbol symbol = session.globalScope;
+
+ return FindPdbFile(pdbFileName, symbol.guid, (int)symbol.age);
+ }
+ }
+
+ return null;
+ }
}
}
diff --git a/ProductionStackTrace.sln b/ProductionStackTrace.sln
index da822c6..a48a19b 100644
--- a/ProductionStackTrace.sln
+++ b/ProductionStackTrace.sln
@@ -1,7 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 2013
-VisualStudioVersion = 12.0.21005.1
+# Visual Studio 14
+VisualStudioVersion = 14.0.25420.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProductionStackTrace", "ProductionStackTrace\ProductionStackTrace.csproj", "{6F8A759B-6096-468E-A370-09C9785D673C}"
EndProject
diff --git a/ProductionStackTrace/ExceptionReporting.cs b/ProductionStackTrace/ExceptionReporting.cs
index 4bc2105..09bb1fb 100644
--- a/ProductionStackTrace/ExceptionReporting.cs
+++ b/ProductionStackTrace/ExceptionReporting.cs
@@ -38,6 +38,7 @@ public static string GetExceptionReport(Exception ex)
{
var info = ctx.AssemblyInfo[key];
builder.AppendFormat("MODULE: {0} => {1};", key, info.Assembly.FullName);
+#if !SILVERLIGHT
if (info.DebugInfo != null)
{
builder.AppendFormat(" G:{0:N}; A:{1}", info.DebugInfo.Guid, info.DebugInfo.Age);
@@ -46,6 +47,7 @@ public static string GetExceptionReport(Exception ex)
if (!string.Equals(pdbFileName, info.ShortName + ".pdb", StringComparison.OrdinalIgnoreCase))
builder.Append("; F:").Append(pdbFileName);
}
+#endif
builder.AppendLine();
}
}
@@ -228,7 +230,9 @@ private static void AppendAssemblyName(StringBuilder builder, Assembly assembly,
if (info == null)
{
ctx.AssemblyInfo.Add(assemblyName, info = new AssemblyReportInfo() { Assembly = assembly, ShortName = originalAssemblyName });
+#if !SILVERLIGHT
info.DebugInfo = AssemblyDebugInfo.ReadAssemblyDebugInfo(assembly);
+#endif
}
}
@@ -243,7 +247,9 @@ private class ExceptionReportingContext
private class AssemblyReportInfo
{
public Assembly Assembly;
+#if !SILVERLIGHT
public AssemblyDebugInfo DebugInfo;
+#endif
public string ShortName;
}
diff --git a/ProductionStackTrace/Internals/AssemblyDebugInfo.cs b/ProductionStackTrace/Internals/AssemblyDebugInfo.cs
index 4d666fb..5578e08 100644
--- a/ProductionStackTrace/Internals/AssemblyDebugInfo.cs
+++ b/ProductionStackTrace/Internals/AssemblyDebugInfo.cs
@@ -18,6 +18,7 @@ private AssemblyDebugInfo()
{
}
+#if !SILVERLIGHT
///
/// Retrieve PDB information from Assembly, by reading it's PE header.
///
@@ -88,6 +89,7 @@ public static AssemblyDebugInfo ReadAssemblyDebugInfo(Assembly assembly)
Path = path
};
}
+#endif
#region Struct definitions
diff --git a/ProductionStackTrace/Internals/PeHeaders.cs b/ProductionStackTrace/Internals/PeHeaders.cs
index 43a2173..3b5cbd7 100644
--- a/ProductionStackTrace/Internals/PeHeaders.cs
+++ b/ProductionStackTrace/Internals/PeHeaders.cs
@@ -416,11 +416,13 @@ private PeHeaders()
{
}
+#if !SILVERLIGHT
public static PeHeaders FromAssembly(Assembly assembly)
{
var modulePtr = Marshal.GetHINSTANCE(assembly.ManifestModule);
return FromUnmanagedPtr(modulePtr);
}
+#endif
public static PeHeaders FromUnmanagedPtr(IntPtr memoryPtr)
{
@@ -512,7 +514,12 @@ private static T FromBinaryReader(BinaryReader reader, byte[] lookahead)
// Pin the managed memory while, copy it out the data, then unpin it
GCHandle handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
+#if SILVERLIGHT
+ T theStructure = default(T);
+ Marshal.PtrToStructure(handle.AddrOfPinnedObject(), theStructure);
+#else
T theStructure = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));
+#endif
handle.Free();
return theStructure;
@@ -520,7 +527,12 @@ private static T FromBinaryReader(BinaryReader reader, byte[] lookahead)
private static T FromMemoryPtr(IntPtr memPtr, ref long index)
{
+#if SILVERLIGHT
+ T obj = default(T);
+ Marshal.PtrToStructure(new IntPtr(memPtr.ToInt64() + index), obj);
+#else
var obj = (T)Marshal.PtrToStructure(new IntPtr(memPtr.ToInt64() + index), typeof(T));
+#endif
index += Marshal.SizeOf(typeof(T));
return obj;
}
@@ -594,7 +606,11 @@ public DateTime TimeStamp
// Add in the number of seconds since 1970/1/1
returnValue = returnValue.AddSeconds(fileHeader.TimeDateStamp);
// Adjust to local timezone
+#if SILVERLIGHT
+ returnValue += TimeZoneInfo.Local.GetUtcOffset(returnValue);
+#else
returnValue += TimeZone.CurrentTimeZone.GetUtcOffset(returnValue);
+#endif
return returnValue;
}
diff --git a/ProductionStackTrace/ProductionStackTrace.csproj b/ProductionStackTrace/ProductionStackTrace.csproj
index 15b085f..8104e16 100644
--- a/ProductionStackTrace/ProductionStackTrace.csproj
+++ b/ProductionStackTrace/ProductionStackTrace.csproj
@@ -11,7 +11,8 @@
ProductionStackTrace
v4.5
512
- bin\$(Configuration)\$(TargetFrameworkVersion)\
+ bin\$(Configuration)\$(TargetFrameworkVersion)\
+ bin\$(Configuration)\sl5\
bin\$(Configuration)
$(OutputPath)\$(AssemblyName).xml
@@ -46,7 +47,8 @@
-
+
+
+
+ $(ProjectDir)$(ProjectName).nuspec
+
+
+
\ No newline at end of file
diff --git a/ProductionStackTrace/ProductionStackTrace.nuspec b/ProductionStackTrace/ProductionStackTrace.nuspec
index 0f75a38..38c6f2b 100644
--- a/ProductionStackTrace/ProductionStackTrace.nuspec
+++ b/ProductionStackTrace/ProductionStackTrace.nuspec
@@ -23,6 +23,7 @@
+
\ No newline at end of file
diff --git a/appveyor.yml b/appveyor.yml
new file mode 100644
index 0000000..ad7028d
--- /dev/null
+++ b/appveyor.yml
@@ -0,0 +1,11 @@
+version: 1.0.{build}
+build_script:
+- cmd: build.cmd package
+test_script:
+- cmd: >-
+ nuget install NUnit.Runners -Version 2.6.4
+
+ .\NUnit.Runners.2.6.4\tools\nunit-console-x86.exe .\ProductionStackTrace.Test\bin\Release\ProductionStackTrace.Test.dll
+artifacts:
+- path: _deploy\*.nupkg
+ name: NuGet Package
\ No newline at end of file