summaryrefslogtreecommitdiff
path: root/src/ToolBox/SOS/NETCore
diff options
context:
space:
mode:
Diffstat (limited to 'src/ToolBox/SOS/NETCore')
-rw-r--r--src/ToolBox/SOS/NETCore/SymbolReader.cs97
-rw-r--r--src/ToolBox/SOS/NETCore/project.json2
2 files changed, 84 insertions, 15 deletions
diff --git a/src/ToolBox/SOS/NETCore/SymbolReader.cs b/src/ToolBox/SOS/NETCore/SymbolReader.cs
index f4a3ce30d8..492f7cbd1f 100644
--- a/src/ToolBox/SOS/NETCore/SymbolReader.cs
+++ b/src/ToolBox/SOS/NETCore/SymbolReader.cs
@@ -28,13 +28,16 @@ namespace SOS
{
public IntPtr points;
public int size;
+ public IntPtr locals;
+ public int localsSize;
+
}
/// <summary>
/// Read memory callback
/// </summary>
/// <returns>number of bytes read or 0 for error</returns>
- internal unsafe delegate int ReadMemoryDelegate(IntPtr address, byte* buffer, int count);
+ internal unsafe delegate int ReadMemoryDelegate(ulong address, byte* buffer, int count);
private sealed class OpenedReader : IDisposable
{
@@ -58,7 +61,7 @@ namespace SOS
/// </summary>
private class TargetStream : Stream
{
- readonly IntPtr _address;
+ readonly ulong _address;
readonly ReadMemoryDelegate _readMemory;
public override long Position { get; set; }
@@ -67,7 +70,7 @@ namespace SOS
public override bool CanRead { get { return true; } }
public override bool CanWrite { get { return false; } }
- public TargetStream(IntPtr address, int size, ReadMemoryDelegate readMemory)
+ public TargetStream(ulong address, int size, ReadMemoryDelegate readMemory)
: base()
{
_address = address;
@@ -86,7 +89,7 @@ namespace SOS
{
fixed (byte* p = &buffer[offset])
{
- int read = _readMemory(new IntPtr(_address.ToInt64() + Position), p, count);
+ int read = _readMemory(_address + (ulong)Position, p, count);
Position += read;
return read;
}
@@ -126,6 +129,19 @@ namespace SOS
}
/// <summary>
+ /// Quick fix for Path.GetFileName which incorrectly handles Windows-style paths on Linux
+ /// </summary>
+ /// <param name="pathName"> File path to be processed </param>
+ /// <returns>Last component of path</returns>
+ private static string GetFileName(string pathName)
+ {
+ int pos = pathName.LastIndexOfAny(new char[] { '/', '\\'});
+ if (pos < 0)
+ return pathName;
+ return pathName.Substring(pos + 1);
+ }
+
+ /// <summary>
/// Checks availability of debugging information for given assembly.
/// </summary>
/// <param name="assemblyPath">
@@ -141,18 +157,18 @@ namespace SOS
/// <param name="inMemoryPdbAddress">in memory PDB address or zero</param>
/// <param name="inMemoryPdbSize">in memory PDB size</param>
/// <returns>Symbol reader handle or zero if error</returns>
- internal static IntPtr LoadSymbolsForModule(string assemblyPath, bool isFileLayout, IntPtr loadedPeAddress, int loadedPeSize,
- IntPtr inMemoryPdbAddress, int inMemoryPdbSize, ReadMemoryDelegate readMemory)
+ internal static IntPtr LoadSymbolsForModule(string assemblyPath, bool isFileLayout, ulong loadedPeAddress, int loadedPeSize,
+ ulong inMemoryPdbAddress, int inMemoryPdbSize, ReadMemoryDelegate readMemory)
{
try
{
TargetStream peStream = null;
- if (assemblyPath == null && loadedPeAddress != IntPtr.Zero)
+ if (assemblyPath == null && loadedPeAddress != 0)
{
peStream = new TargetStream(loadedPeAddress, loadedPeSize, readMemory);
}
TargetStream pdbStream = null;
- if (inMemoryPdbAddress != IntPtr.Zero)
+ if (inMemoryPdbAddress != 0)
{
pdbStream = new TargetStream(inMemoryPdbAddress, inMemoryPdbSize, readMemory);
}
@@ -207,7 +223,7 @@ namespace SOS
try
{
- string fileName = Path.GetFileName(filePath);
+ string fileName = GetFileName(filePath);
foreach (MethodDebugInformationHandle methodDebugInformationHandle in reader.MethodDebugInformation)
{
MethodDebugInformation methodDebugInfo = reader.GetMethodDebugInformation(methodDebugInformationHandle);
@@ -215,7 +231,7 @@ namespace SOS
foreach (SequencePoint point in sequencePoints)
{
string sourceName = reader.GetString(reader.GetDocument(point.Document).Name);
- if (point.StartLine == lineNumber && Path.GetFileName(sourceName) == fileName)
+ if (point.StartLine == lineNumber && GetFileName(sourceName) == fileName)
{
methodToken = MetadataTokens.GetToken(methodDebugInformationHandle.ToDefinitionHandle());
ilOffset = point.Offset;
@@ -378,7 +394,48 @@ namespace SOS
}
return false;
}
+ internal static bool GetLocalsInfoForMethod(string assemblyPath, int methodToken, out List<string> locals)
+ {
+ locals = null;
+
+ OpenedReader openedReader = GetReader(assemblyPath, isFileLayout: true, peStream: null, pdbStream: null);
+ if (openedReader == null)
+ return false;
+
+ using (openedReader)
+ {
+ try
+ {
+ Handle handle = MetadataTokens.Handle(methodToken);
+ if (handle.Kind != HandleKind.MethodDefinition)
+ return false;
+
+ locals = new List<string>();
+ MethodDebugInformationHandle methodDebugHandle =
+ ((MethodDefinitionHandle)handle).ToDebugInformationHandle();
+ LocalScopeHandleCollection localScopes = openedReader.Reader.GetLocalScopes(methodDebugHandle);
+ foreach (LocalScopeHandle scopeHandle in localScopes)
+ {
+ LocalScope scope = openedReader.Reader.GetLocalScope(scopeHandle);
+ LocalVariableHandleCollection localVars = scope.GetLocalVariables();
+ foreach (LocalVariableHandle varHandle in localVars)
+ {
+ LocalVariable localVar = openedReader.Reader.GetLocalVariable(varHandle);
+ if (localVar.Attributes == LocalVariableAttributes.DebuggerHidden)
+ continue;
+ locals.Add(openedReader.Reader.GetString(localVar.Name));
+ }
+ }
+ }
+ catch
+ {
+ return false;
+ }
+ }
+ return true;
+
+ }
/// <summary>
/// Returns source name, line numbers and IL offsets for given method token.
/// </summary>
@@ -392,11 +449,17 @@ namespace SOS
try
{
List<DebugInfo> points = null;
+ List<string> locals = null;
if (!GetDebugInfoForMethod(assemblyPath, methodToken, out points))
{
return false;
}
+
+ if (!GetLocalsInfoForMethod(assemblyPath, methodToken, out locals))
+ {
+ return false;
+ }
var structSize = Marshal.SizeOf<DebugInfo>();
debugInfo.size = points.Count;
@@ -407,6 +470,14 @@ namespace SOS
Marshal.StructureToPtr(info, ptr, false);
ptr = (IntPtr)(ptr.ToInt64() + structSize);
}
+ debugInfo.localsSize = locals.Count;
+ debugInfo.locals = Marshal.AllocHGlobal(debugInfo.localsSize * Marshal.SizeOf<IntPtr>());
+ IntPtr ptrLocals = debugInfo.locals;
+ foreach (string s in locals)
+ {
+ Marshal.WriteIntPtr(ptrLocals, Marshal.StringToHGlobalUni(s));
+ ptrLocals += Marshal.SizeOf<IntPtr>();
+ }
return true;
}
catch
@@ -446,12 +517,10 @@ namespace SOS
foreach (SequencePoint point in sequencePoints)
{
- if (point.StartLine == 0 || point.StartLine == SequencePoint.HiddenLine)
- continue;
DebugInfo debugInfo = new DebugInfo();
debugInfo.lineNumber = point.StartLine;
- debugInfo.fileName = openedReader.Reader.GetString(openedReader.Reader.GetDocument(point.Document).Name);
+ debugInfo.fileName = GetFileName(openedReader.Reader.GetString(openedReader.Reader.GetDocument(point.Document).Name));
debugInfo.ilOffset = point.Offset;
points.Add(debugInfo);
}
@@ -609,7 +678,7 @@ namespace SOS
{
try
{
- pdbPath = Path.Combine(Path.GetDirectoryName(assemblyPath), Path.GetFileName(pdbPath));
+ pdbPath = Path.Combine(Path.GetDirectoryName(assemblyPath), GetFileName(pdbPath));
}
catch
{
diff --git a/src/ToolBox/SOS/NETCore/project.json b/src/ToolBox/SOS/NETCore/project.json
index e9e4f0999f..7a3cf4fe1d 100644
--- a/src/ToolBox/SOS/NETCore/project.json
+++ b/src/ToolBox/SOS/NETCore/project.json
@@ -3,7 +3,7 @@
"Microsoft.NETCore.Platforms": "1.0.1",
"System.IO.FileSystem": "4.0.1",
"System.Runtime.InteropServices": "4.1.0",
- "System.Reflection.Metadata": "1.4.1-beta-24417-02"
+ "System.Reflection.Metadata": "1.4.1"
},
"frameworks": {
"netcoreapp1.0": {}