Skip to content

Commit

Permalink
Added support for generating and analyzing Silverlight 5 exception st…
Browse files Browse the repository at this point in the history
…ack trace reports
  • Loading branch information
icnocop committed Mar 13, 2018
1 parent fe3b25e commit 43810a1
Show file tree
Hide file tree
Showing 12 changed files with 205 additions and 15 deletions.
1 change: 1 addition & 0 deletions .nuget/BuildCommon.targets
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
<!-- Set compile time constants to detect target framework version during compilation -->
<CustomConstants Condition=" '$(TargetFrameworkVersion)' == 'v2.0' ">TARGET_NET_20</CustomConstants>
<CustomConstants Condition=" '$(TargetFrameworkVersion)' == 'v4.0' ">TARGET_NET_40</CustomConstants>
<CustomConstants Condition=" '$(TargetFrameworkIdentifier)' == 'Silverlight' ">SILVERLIGHT</CustomConstants>
<DefineConstants Condition=" '$(DefineConstants)' != '' And '$(CustomConstants)' != '' ">$(DefineConstants);</DefineConstants>
<DefineConstants>$(DefineConstants)$(CustomConstants)</DefineConstants>
</PropertyGroup>
Expand Down
31 changes: 21 additions & 10 deletions ProductionStackTrace.Analyze/ExceptionReportInterpreter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public class ExceptionReportInterpreter
// MODULE: AssemblyName => AssemblyFullyQualifiedName; G:27657a27fg376787d6; A:1

private static readonly Regex s_regexAssemblyMapping =
new Regex(@"MODULE: (?<Assembly>[^\s]+(?=\s+\=>))\s+\=>\s+(?<AssemblyFQN>[^;]+)(;\s+(?<KeyValue>[a-z]+\:[^;]+))+", RegexOptions.Singleline | RegexOptions.CultureInvariant | RegexOptions.IgnoreCase);
new Regex(@"MODULE: (?<Assembly>[^\s]+(?=\s+\=>))\s+\=>\s+(?<AssemblyFQN>[^;]+)(;(\s+)?(?<KeyValue>[a-z]+\:[^;]+)?)+", RegexOptions.Singleline | RegexOptions.CultureInvariant | RegexOptions.IgnoreCase);

private SymbolSearch _symSearch;

Expand Down Expand Up @@ -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

Expand All @@ -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;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
<ItemGroup>
<Reference Include="dia2lib" Condition="'$(TargetFrameworkVersion)' != 'v2.0'">
<HintPath>..\Lib\dia2lib\net40\dia2lib.dll</HintPath>
<EmbedInteropTypes>True</EmbedInteropTypes>
<EmbedInteropTypes>False</EmbedInteropTypes>
</Reference>
<Reference Include="dia2lib" Condition="'$(TargetFrameworkVersion)' == 'v2.0'">
<HintPath>..\Lib\dia2lib\net20\dia2lib.dll</HintPath>
Expand Down
31 changes: 30 additions & 1 deletion ProductionStackTrace.Analyze/SymbolSearch.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using System;
using Dia2Lib;
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;

Expand Down Expand Up @@ -116,5 +118,32 @@ public string FindPdbFile(string pdbFileName, Guid guid, int age)

return filePath.ToString();
}

/// <summary>
/// Looks through the configured symbol paths to find a PDB symbol
/// file matching specified name.
/// </summary>
/// <param name="pdbFileName">Name of the PDB file.</param>
/// <returns>The pdb file path or null the pdf file wasn't found.</returns>
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;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.50727</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{2122731C-6CEA-47E2-A7E1-349523009FAF}</ProjectGuid>
<ProjectTypeGuids>{A1591282-1198-4647-A2B1-27E5FF5F6F3B};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>ProductionStackTrace</RootNamespace>
<AssemblyName>ProductionStackTrace.Silverlight</AssemblyName>
<TargetFrameworkIdentifier>Silverlight</TargetFrameworkIdentifier>
<TargetFrameworkVersion>v5.0</TargetFrameworkVersion>
<SilverlightVersion>$(TargetFrameworkVersion)</SilverlightVersion>
<SilverlightApplication>false</SilverlightApplication>
<ValidateXaml>true</ValidateXaml>
<ThrowErrorsInValidation>true</ThrowErrorsInValidation>
</PropertyGroup>
<!-- This property group is only here to support building this project using the
MSBuild 3.5 toolset. In order to work correctly with this older toolset, it needs
to set the TargetFrameworkVersion to v3.5 -->
<PropertyGroup Condition="'$(MSBuildToolsVersion)' == '3.5'">
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>Bin\Debug</OutputPath>
<DefineConstants>DEBUG;TRACE;SILVERLIGHT</DefineConstants>
<NoStdLib>true</NoStdLib>
<NoConfig>true</NoConfig>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>Bin\Release</OutputPath>
<DefineConstants>TRACE;SILVERLIGHT</DefineConstants>
<NoStdLib>true</NoStdLib>
<NoConfig>true</NoConfig>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="mscorlib" />
<Reference Include="System.Windows" />
<Reference Include="system" />
<Reference Include="System.Core">
<HintPath>$(TargetFrameworkDirectory)System.Core.dll</HintPath>
</Reference>
<Reference Include="System.Xml" />
<Reference Include="System.Net" />
<Reference Include="System.Windows.Browser" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\ProductionStackTrace\ExceptionEx.cs">
<Link>ExceptionEx.cs</Link>
</Compile>
<Compile Include="..\ProductionStackTrace\ExceptionReporting.cs">
<Link>ExceptionReporting.cs</Link>
</Compile>
<Compile Include="..\ProductionStackTrace\Internals\AssemblyDebugInfo.cs">
<Link>Internals\AssemblyDebugInfo.cs</Link>
</Compile>
<Compile Include="..\ProductionStackTrace\Internals\PeHeaders.cs">
<Link>Internals\PeHeaders.cs</Link>
</Compile>
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\Silverlight\$(SilverlightVersion)\Microsoft.Silverlight.CSharp.targets" />
<ProjectExtensions>
<VisualStudio>
<FlavorProperties GUID="{A1591282-1198-4647-A2B1-27E5FF5F6F3B}">
<SilverlightProjectProperties />
</FlavorProperties>
</VisualStudio>
</ProjectExtensions>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
31 changes: 31 additions & 0 deletions ProductionStackTrace.Silverlight/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("ProductionStackTrace.Silverlight")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCulture("")]

// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]

// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("2122731c-6cea-47e2-a7e1-349523009faf")]

// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
10 changes: 8 additions & 2 deletions ProductionStackTrace.sln
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -27,6 +27,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "root", "root", "{03B97452-6
CommonAssemblyInfo.cs = CommonAssemblyInfo.cs
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProductionStackTrace.Silverlight", "ProductionStackTrace.Silverlight\ProductionStackTrace.Silverlight.csproj", "{2122731C-6CEA-47E2-A7E1-349523009FAF}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -53,6 +55,10 @@ Global
{AD70438D-18CF-46F5-84DD-4D79B9FB2876}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AD70438D-18CF-46F5-84DD-4D79B9FB2876}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AD70438D-18CF-46F5-84DD-4D79B9FB2876}.Release|Any CPU.Build.0 = Release|Any CPU
{2122731C-6CEA-47E2-A7E1-349523009FAF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2122731C-6CEA-47E2-A7E1-349523009FAF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2122731C-6CEA-47E2-A7E1-349523009FAF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2122731C-6CEA-47E2-A7E1-349523009FAF}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
2 changes: 2 additions & 0 deletions ProductionStackTrace/ExceptionReporting.cs
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,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
}
}

Expand Down
2 changes: 2 additions & 0 deletions ProductionStackTrace/Internals/AssemblyDebugInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ private AssemblyDebugInfo()
{
}

#if !SILVERLIGHT
/// <summary>
/// Retrieve PDB information from Assembly, by reading it's PE header.
/// </summary>
Expand Down Expand Up @@ -88,6 +89,7 @@ public static AssemblyDebugInfo ReadAssemblyDebugInfo(Assembly assembly)
Path = path
};
}
#endif

#region Struct definitions

Expand Down
16 changes: 16 additions & 0 deletions ProductionStackTrace/Internals/PeHeaders.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -512,15 +514,25 @@ private static T FromBinaryReader<T>(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;
}

private static T FromMemoryPtr<T>(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;
}
Expand Down Expand Up @@ -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;
}
Expand Down
4 changes: 3 additions & 1 deletion ProductionStackTrace/ProductionStackTrace.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
<AssemblyName>ProductionStackTrace</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<OutputPath>bin\$(Configuration)\$(TargetFrameworkVersion)\</OutputPath>
<OutputPath Condition="'$(TargetFrameworkIdentifier)'==''">bin\$(Configuration)\$(TargetFrameworkVersion)\</OutputPath>
<OutputPath Condition="'$(TargetFrameworkIdentifier)'=='Silverlight' and $(TargetFrameworkVersion) == 'v5.0'">bin\$(Configuration)\sl5\</OutputPath>
<PackageOutputDir>bin\$(Configuration)</PackageOutputDir>
<DocumentationFile>$(OutputPath)\$(AssemblyName).xml</DocumentationFile>
</PropertyGroup>
Expand Down Expand Up @@ -59,5 +60,6 @@
<Target Name="AfterBuild" Condition="'$(TargetFrameworkVersion)' == 'v4.5'">
<MSBuild Projects="$(MSBuildProjectFile)" Targets="Build" Properties="TargetFrameworkVersion=v4.0;TargetFrameworkProfile=Client;Configuration=$(Configuration);Platform=$(Platform)" />
<MSBuild Projects="$(MSBuildProjectFile)" Targets="Build" Properties="TargetFrameworkVersion=v2.0;Configuration=$(Configuration);Platform=$(Platform)" />
<MSBuild Projects="$(MSBuildProjectFile)" Targets="Build" Properties="TargetFrameworkVersion=v5.0;TargetFrameworkIdentifier=Silverlight;Configuration=$(Configuration);Platform=$(Platform)" />
</Target>
</Project>
1 change: 1 addition & 0 deletions ProductionStackTrace/ProductionStackTrace.nuspec
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
<file src="bin\$configuration$\v2.0\*" exclude="**\*.tmp" target="lib\net20\" />
<file src="bin\$configuration$\v4.0\*" exclude="**\*.tmp" target="lib\net40\" />
<file src="bin\$configuration$\v4.5\*" exclude="**\*.tmp" target="lib\net45\" />
<file src="bin\$configuration$\sl5\*" exclude="**\*.tmp" target="lib\sl5\" />
<file src="**\*.cs" exclude="obj\**" target="src" />
</files>
</package>

0 comments on commit 43810a1

Please sign in to comment.