-
-
Notifications
You must be signed in to change notification settings - Fork 207
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add a small test program to get il offset + metadata tokens
- Loading branch information
Showing
2 changed files
with
181 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,165 @@ | ||
using System; | ||
using System.Diagnostics; | ||
using System.Reflection; | ||
using System.Reflection.Metadata; | ||
using System.Reflection.PortableExecutable; | ||
|
||
[assembly: DebuggableAttribute(true, false)] | ||
|
||
class StackTraceSample | ||
{ | ||
[STAThread] | ||
static void Main(string[] args) | ||
{ | ||
StackTraceSample sample = new StackTraceSample(); | ||
var module = sample.GetType().Module; | ||
Console.WriteLine("Module: {0}", module); | ||
|
||
Console.WriteLine("Offset Unknown: {0}", StackFrame.OFFSET_UNKNOWN); | ||
|
||
sample.MyPublicMethod(); | ||
|
||
/*try | ||
{ | ||
sample.MyPublicMethod(); | ||
} | ||
catch (Exception) | ||
{ | ||
using (SentrySdk.Init("https://[email protected]/5428537")) | ||
{ | ||
// The following exception is captured and sent to Sentry | ||
throw null; | ||
} | ||
}*/ | ||
} | ||
|
||
public void MyPublicMethod() | ||
{ | ||
MyProtectedMethod(); | ||
} | ||
|
||
protected void MyProtectedMethod() | ||
{ | ||
MyInternalClass mic = new MyInternalClass(); | ||
} | ||
|
||
class MyInternalClass | ||
{ | ||
public MyInternalClass() | ||
{ | ||
ThrowsException(); | ||
} | ||
|
||
public string GetPdbId(Module module) | ||
{ | ||
var name = module.FullyQualifiedName; | ||
if (!File.Exists(name)) | ||
{ | ||
return null; | ||
} | ||
using var stream = File.OpenRead(name); | ||
var peReader = new PEReader(stream); | ||
|
||
var codeView = peReader.ReadDebugDirectory() | ||
.FirstOrDefault(d => d.Type == DebugDirectoryEntryType.CodeView); | ||
if (codeView.Type == DebugDirectoryEntryType.Unknown) | ||
{ | ||
return null; | ||
} | ||
|
||
var data = peReader.ReadCodeViewDebugDirectoryData(codeView); | ||
|
||
var signature = data.Guid; | ||
var age = data.Age; | ||
var file = data.Path; | ||
|
||
// Version Major=any, Minor=0x504d of the data format has the same structure as above. | ||
// The Age shall be 1. The format of the .pdb file that this PE/COFF file was built with is Portable PDB. | ||
// The Major version specified in the entry indicates the version of the Portable PDB format. | ||
// Together 16B of the Guid concatenated with 4B of the TimeDateStamp field of the entry form a PDB ID that | ||
// should be used to match the PE/COFF image with the associated PDB (instead of Guid and Age). | ||
// Matching PDB ID is stored in the #Pdb stream of the .pdb file. | ||
// See https://github.com/dotnet/runtime/blob/main/docs/design/specs/PE-COFF.md#codeview-debug-directory-entry-type-2 | ||
if (codeView.MinorVersion == 0x504d) | ||
{ | ||
return String.Format("{0}-{1:x}", signature, codeView.Stamp); | ||
} | ||
return String.Format("{0}-{1:x}", signature, age); | ||
} | ||
|
||
public void ThrowsException() | ||
{ | ||
try | ||
{ | ||
throw new Exception("A problem was encountered."); | ||
} | ||
catch (Exception) | ||
{ | ||
// Create a StackTrace that captures filename, | ||
// line number and column information. | ||
StackTrace st = new StackTrace(true); | ||
string stackIndent = ""; | ||
for (int i = 0; i < st.FrameCount; i++) | ||
{ | ||
// Note that at this level, there are four | ||
// stack frames, one for each method invocation. | ||
StackFrame sf = st.GetFrame(i); | ||
var method = sf.GetMethod(); | ||
|
||
Console.WriteLine(); | ||
Console.WriteLine(stackIndent + " Method: {0}", | ||
method); | ||
Console.WriteLine(stackIndent + " File: {0}", | ||
sf.GetFileName()); | ||
Console.WriteLine(stackIndent + " Line Number: {0}", | ||
sf.GetFileLineNumber()); | ||
|
||
var offset = sf.GetILOffset(); | ||
var token = method.MetadataToken; | ||
|
||
Console.WriteLine(); | ||
Console.WriteLine(stackIndent + " IL Offset: {0}", | ||
offset); | ||
Console.WriteLine(stackIndent + " Metadata Token: 0x{0:X8}", | ||
token); | ||
|
||
// the top byte is the token type, the lower three bytes are the record id | ||
// See: https://docs.microsoft.com/en-us/previous-versions/dotnet/netframework-4.0/ms404456(v=vs.100)#metadata-token-structure | ||
var tokenType = token & 0xff000000; | ||
// See https://docs.microsoft.com/en-us/dotnet/framework/unmanaged-api/metadata/cortokentype-enumeration | ||
if (tokenType == 0x06000000) | ||
{ | ||
var recordId = token & 0x00ffffff; | ||
|
||
Console.WriteLine(stackIndent + " MethodDef Record ID: {0}", | ||
recordId); | ||
} | ||
|
||
var module = method.Module; | ||
|
||
Console.WriteLine(); | ||
Console.WriteLine(stackIndent + " Module Name: {0}", | ||
module.FullyQualifiedName); | ||
Console.WriteLine(stackIndent + " Module Metadata Token: 0x{0:X8}", | ||
module.MetadataToken); | ||
|
||
// > In unmanaged metadata, the GUID returned by the ModuleVersionId property is referred to as the mvid, and is stored in the GUID heap. | ||
// See: https://docs.microsoft.com/en-us/dotnet/api/system.reflection.module.moduleversionid?view=net-6.0#remarks | ||
Console.WriteLine(stackIndent + " Module Version Id: {0}", | ||
module.ModuleVersionId); | ||
|
||
Console.WriteLine(stackIndent + " PdbId: {0}", | ||
GetPdbId(module) ?? "<unknown>"); | ||
|
||
stackIndent += " "; | ||
} | ||
|
||
Console.WriteLine(); | ||
|
||
//throw e; | ||
throw; | ||
} | ||
} | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<OutputType>Exe</OutputType> | ||
<TargetFramework>net6.0</TargetFramework> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<!--<Nullable>enable</Nullable>--> | ||
<DebugType>pdbonly</DebugType> | ||
<Optimize>true</Optimize> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="../../src/Sentry/Sentry.csproj" /> | ||
</ItemGroup> | ||
|
||
</Project> |