Imported Upstream version 4.0.0~alpha1

Former-commit-id: 806294f5ded97629b74c85c09952f2a74fe182d9
This commit is contained in:
Jo Shields
2015-04-07 09:35:12 +01:00
parent 283343f570
commit 3c1f479b9d
22469 changed files with 2931443 additions and 869343 deletions

View File

@@ -0,0 +1,144 @@
using System;
using System.IO;
using System.Linq;
using System.Diagnostics;
using System.Collections.Generic;
using Mono.Cecil;
using Mono.CompilerServices.SymbolWriter;
namespace Symbolicate
{
struct Location {
public string FileName;
public int Line;
}
class LocationProvider {
class AssemblyLocationProvider {
AssemblyDefinition assembly;
MonoSymbolFile symbolFile;
public AssemblyLocationProvider (AssemblyDefinition assembly, MonoSymbolFile symbolFile)
{
this.assembly = assembly;
this.symbolFile = symbolFile;
}
public bool TryGetLocation (string methodFullName, string[] methodParamsTypes, int ilOffset, out Location location)
{
location = default (Location);
if (symbolFile == null)
return false;
var typeNameEnd = methodFullName.LastIndexOf (".");
var typeName = methodFullName.Substring (0, typeNameEnd);
var methodName = methodFullName.Substring (typeNameEnd + 1, methodFullName.Length - typeNameEnd - 1);
var type = assembly.MainModule.Types.FirstOrDefault (t => t.FullName == typeName);
if (type == null)
return false;
var method = type.Methods.FirstOrDefault (m => {
if (m.Name != methodName)
return false;
if (m.Parameters.Count != methodParamsTypes.Length)
return false;
for (var i = 0; i < methodParamsTypes.Length; i++) {
var paramType = m.Parameters[i].ParameterType;
if (paramType.Name != methodParamsTypes[i])
return false;
}
return true;
});
if (method == null)
return false;
var methodSymbol = symbolFile.Methods [method.MetadataToken.RID-1];
foreach (var lineNumber in methodSymbol.GetLineNumberTable ().LineNumbers) {
if (lineNumber.Offset < ilOffset)
continue;
location.FileName = symbolFile.Sources [lineNumber.File-1].FileName;
location.Line = lineNumber.Row;
return true;
}
return false;
}
}
Dictionary<string, AssemblyLocationProvider> assemblies;
HashSet<string> directories;
public LocationProvider () {
assemblies = new Dictionary<string, AssemblyLocationProvider> ();
directories = new HashSet<string> ();
}
public void AddAssembly (string assemblyPath)
{
assemblyPath = Path.GetFullPath (assemblyPath);
if (assemblies.ContainsKey (assemblyPath))
return;
if (!File.Exists (assemblyPath))
throw new ArgumentException ("assemblyPath does not exist: "+ assemblyPath);
var assembly = AssemblyDefinition.ReadAssembly (assemblyPath);
MonoSymbolFile symbolFile = null;
var symbolPath = assemblyPath + ".mdb";
if (!File.Exists (symbolPath))
Debug.WriteLine (".mdb file was not found for " + assemblyPath);
else
symbolFile = MonoSymbolFile.ReadSymbolFile (assemblyPath + ".mdb");
assemblies.Add (assemblyPath, new AssemblyLocationProvider (assembly, symbolFile));
directories.Add (Path.GetDirectoryName (assemblyPath));
foreach (var assemblyRef in assembly.MainModule.AssemblyReferences) {
string refPath = null;
foreach (var dir in directories) {
refPath = Path.Combine (dir, assemblyRef.Name);
if (File.Exists (refPath))
break;
refPath = Path.Combine (dir, assemblyRef.Name + ".dll");
if (File.Exists (refPath))
break;
refPath = Path.Combine (dir, assemblyRef.Name + ".exe");
if (File.Exists (refPath))
break;
refPath = null;
}
if (refPath != null)
AddAssembly (refPath);
}
}
public void AddDirectory (string directory)
{
if (Directory.Exists (directory))
throw new ArgumentException ("Directory " + directory + " does not exist.");
directories.Add (directory);
}
public bool TryGetLocation (string methodName, string[] methodParams, int ilOffset, out Location location)
{
location = default (Location);
foreach (var assembly in assemblies.Values) {
if (assembly.TryGetLocation (methodName, methodParams, ilOffset, out location))
return true;
}
return false;
}
}
}

View File

@@ -0,0 +1,39 @@
thisdir = tools/symbolicate
SUBDIRS =
include ../../build/rules.make
PROGRAM = symbolicate.exe
LOCAL_MCS_FLAGS = \
/r:Mono.Cecil.dll \
/r:Mono.CompilerServices.SymbolWriter.dll \
/r:System.Xml
include ../../build/executable.make
LIB_PATH = $(topdir)/class/lib/$(PROFILE)
MONO = MONO_PATH=$(LIB_PATH)$(PLATFORM_PATH_SEPARATOR)$$MONO_PATH $(RUNTIME)
OUT_DIR = Test/out
TEST_CS = Test/StackTraceDumper.cs
TEST_EXE = $(OUT_DIR)/StackTraceDumper.exe
RELEASE_FILE = $(OUT_DIR)/release.out
SYMBOLICATE_FILE = $(OUT_DIR)/symbolicate.out
SYMBOLICATE_EXPECTED_FILE = Test/symbolicate.expected
build-test:
@mkdir -p $(OUT_DIR)
@$(MCS) -debug $(TEST_CS) -out:$(TEST_EXE)
check: all build-test
@MONO_DEBUG=gen-compact-seq-points $(MONO) $(TEST_EXE) > $(RELEASE_FILE)
@$(MONO) $(LIB_PATH)/symbolicate.exe $(TEST_EXE) $(RELEASE_FILE) | sed "s/\[.*Test\//in /" > $(SYMBOLICATE_FILE)
@DIFF=$$(diff $(SYMBOLICATE_FILE) $(SYMBOLICATE_EXPECTED_FILE)); \
if [ ! -z "$$DIFF" ]; then \
echo "Symbolicate tests failed."; \
echo "If $(SYMBOLICATE_FILE) is correct copy it to $(SYMBOLICATE_EXPECTED_FILE)."; \
echo "Otherwise runtime sequence points need to be fixed."; \
echo "$$DIFF"; \
exit 1; \
fi

View File

@@ -0,0 +1,69 @@
using System;
using System.IO;
using System.Globalization;
using System.Text.RegularExpressions;
namespace Symbolicate
{
public class Program
{
static Regex regex = new Regex (@"\w*at (?<MethodName>.+) \((?<MethodParams>.*)\) \[0x(?<IL>.+)\] in <filename unknown>:0");
public static int Main (String[] args)
{
if (args.Length < 2) {
Console.Error.WriteLine ("Usage: symbolicate <assembly path> <input file> [lookup directories]");
return 1;
}
var assemblyPath = args [0];
var inputFile = args [1];
var locProvider = new LocationProvider ();
for (var i = 2; i < args.Length; i++)
locProvider.AddDirectory (args [i]);
locProvider.AddAssembly (assemblyPath);
using (StreamReader r = new StreamReader (inputFile)) {
for (var line = r.ReadLine (); line != null; line = r.ReadLine ()) {
line = SymbolicateLine (line, locProvider);
Console.WriteLine (line);
}
}
return 0;
}
static string SymbolicateLine (string line, LocationProvider locProvider)
{
var match = regex.Match (line);
if (!match.Success)
return line;
var methodName = match.Groups ["MethodName"].Value;
var methodParams = ParseParametersTypes (match.Groups ["MethodParams"].Value);
var ilOffset = int.Parse (match.Groups ["IL"].Value, NumberStyles.HexNumber, CultureInfo.InvariantCulture);
Location location;
if (!locProvider.TryGetLocation (methodName, methodParams, ilOffset, out location))
return line;
return line.Replace ("<filename unknown>:0", string.Format ("{0}:{1}", location.FileName, location.Line));
}
static string[] ParseParametersTypes (string parameters)
{
if (string.IsNullOrEmpty (parameters))
return new string [0];
var paramsArray = parameters.Split (',');
var paramsTypes = new string [paramsArray.Length];
for (var i = 0; i < paramsArray.Length; i++)
paramsTypes [i] = paramsArray [i].Trim ().Split (new char[]{' '}, 2)[0];
return paramsTypes;
}
}
}

View File

@@ -0,0 +1,2 @@
symbolicate.cs
LocationProvider.cs