Renamed the tool to a name that will not conflict with other installed tools.
--- /dev/null
+/Test/out
\ No newline at end of file
--- /dev/null
+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;
+ }
+ }
+}
+
--- /dev/null
+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
--- /dev/null
+Mono Symbolicate Tool - README
+
+symbolicate is a tool that converts a stack trace with `<filename unknown>:0`
+into one with file names and line numbers.
+
+Usage
+-----------------------------
+
+The tool takes as input an exe, a file with stack traces and optionaly one or
+more directories where referenced assemblies mdb files are located.
+
+The output of calling this tool will be the provided file with
+stack traces where `<filename unknown>:0` parts are replaced by
+a file name and a line number.
+
+To use the tool, run the following command:
+
+ mono symbolicate.exe your.exe filewithstacktraces [mdbfolders]
\ No newline at end of file
--- /dev/null
+using System;
+
+class StackTraceDumper {
+ public static void Main () {
+ // Stacktrace with no depth
+ try {
+ throw new Exception ();
+ } catch (Exception e) {
+ Console.WriteLine (e);
+ }
+ // Stacktrace with depth of 1
+ try {
+ ThrowException ();
+ } catch (Exception e) {
+ Console.WriteLine (e);
+ }
+ // Stacktrace with depth of 2
+ try {
+ ThrowException2 ();
+ } catch (Exception e) {
+ Console.WriteLine (e);
+ }
+ }
+
+ public static void ThrowException () {
+ Console.WriteLine ("Exception is not in the first line!");
+ throw new Exception ();
+ }
+
+ public static void ThrowException2 () {
+ ThrowException ();
+ }
+
+}
\ No newline at end of file
--- /dev/null
+System.Exception: Exception of type 'System.Exception' was thrown.
+ at StackTraceDumper.Main () in StackTraceDumper.cs:7
+Exception is not in the first line!
+System.Exception: Exception of type 'System.Exception' was thrown.
+ at StackTraceDumper.ThrowException () in StackTraceDumper.cs:27
+ at StackTraceDumper.Main () in StackTraceDumper.cs:13
+Exception is not in the first line!
+System.Exception: Exception of type 'System.Exception' was thrown.
+ at StackTraceDumper.ThrowException () in StackTraceDumper.cs:27
+ at StackTraceDumper.ThrowException2 () in StackTraceDumper.cs:31
+ at StackTraceDumper.Main () in StackTraceDumper.cs:19
--- /dev/null
+symbolicate.cs
+LocationProvider.cs
\ No newline at end of file
--- /dev/null
+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;
+ }
+ }
+}
\ No newline at end of file
+++ /dev/null
-/Test/out
\ No newline at end of file
+++ /dev/null
-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;
- }
- }
-}
-
+++ /dev/null
-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
+++ /dev/null
-Mono Symbolicate Tool - README
-
-symbolicate is a tool that converts a stack trace with `<filename unknown>:0`
-into one with file names and line numbers.
-
-Usage
------------------------------
-
-The tool takes as input an exe, a file with stack traces and optionaly one or
-more directories where referenced assemblies mdb files are located.
-
-The output of calling this tool will be the provided file with
-stack traces where `<filename unknown>:0` parts are replaced by
-a file name and a line number.
-
-To use the tool, run the following command:
-
- mono symbolicate.exe your.exe filewithstacktraces [mdbfolders]
\ No newline at end of file
+++ /dev/null
-using System;
-
-class StackTraceDumper {
- public static void Main () {
- // Stacktrace with no depth
- try {
- throw new Exception ();
- } catch (Exception e) {
- Console.WriteLine (e);
- }
- // Stacktrace with depth of 1
- try {
- ThrowException ();
- } catch (Exception e) {
- Console.WriteLine (e);
- }
- // Stacktrace with depth of 2
- try {
- ThrowException2 ();
- } catch (Exception e) {
- Console.WriteLine (e);
- }
- }
-
- public static void ThrowException () {
- Console.WriteLine ("Exception is not in the first line!");
- throw new Exception ();
- }
-
- public static void ThrowException2 () {
- ThrowException ();
- }
-
-}
\ No newline at end of file
+++ /dev/null
-System.Exception: Exception of type 'System.Exception' was thrown.
- at StackTraceDumper.Main () in StackTraceDumper.cs:7
-Exception is not in the first line!
-System.Exception: Exception of type 'System.Exception' was thrown.
- at StackTraceDumper.ThrowException () in StackTraceDumper.cs:27
- at StackTraceDumper.Main () in StackTraceDumper.cs:13
-Exception is not in the first line!
-System.Exception: Exception of type 'System.Exception' was thrown.
- at StackTraceDumper.ThrowException () in StackTraceDumper.cs:27
- at StackTraceDumper.ThrowException2 () in StackTraceDumper.cs:31
- at StackTraceDumper.Main () in StackTraceDumper.cs:19
+++ /dev/null
-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;
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-symbolicate.cs
-LocationProvider.cs
\ No newline at end of file