3 using System.Globalization;
4 using System.Text.RegularExpressions;
10 static Regex regex = new Regex (@"\w*at (?<Method>.+) *(\[0x(?<IL>.+)\]|<0x.+ \+ 0x(?<NativeOffset>.+)>( (?<MethodIndex>\d+)|)) in <filename unknown>:0");
12 public static int Main (String[] args)
14 if (args.Length < 2) {
15 Console.Error.WriteLine ("Usage: symbolicate <assembly path> <input file> [lookup directories]");
19 var assemblyPath = args [0];
20 var inputFile = args [1];
22 var locProvider = new LocationProvider ();
24 for (var i = 2; i < args.Length; i++)
25 locProvider.AddDirectory (args [i]);
27 locProvider.AddAssembly (assemblyPath);
29 using (StreamReader r = new StreamReader (inputFile)) {
30 for (var line = r.ReadLine (); line != null; line = r.ReadLine ()) {
31 line = SymbolicateLine (line, locProvider);
32 Console.WriteLine (line);
39 static string SymbolicateLine (string line, LocationProvider locProvider)
41 var match = regex.Match (line);
45 string typeFullName, methodSignature;
46 var methodStr = match.Groups ["Method"].Value.Trim ();
47 if (!ExtractSignatures (methodStr, out typeFullName, out methodSignature))
50 var isOffsetIL = !string.IsNullOrEmpty (match.Groups ["IL"].Value);
51 var offsetVarName = (isOffsetIL)? "IL" : "NativeOffset";
52 var offset = int.Parse (match.Groups [offsetVarName].Value, NumberStyles.HexNumber, CultureInfo.InvariantCulture);
54 uint methodIndex = 0xffffff;
55 if (!string.IsNullOrEmpty (match.Groups ["MethodIndex"].Value))
56 methodIndex = uint.Parse (match.Groups ["MethodIndex"].Value, CultureInfo.InvariantCulture);
58 var loc = locProvider.TryGetLocation (typeFullName, methodSignature, offset, isOffsetIL, methodIndex);
62 return line.Replace ("<filename unknown>:0", string.Format ("{0}:{1}", loc.Document.Url, loc.StartLine));
65 static bool ExtractSignatures (string str, out string typeFullName, out string methodSignature)
67 var methodNameEnd = str.IndexOf ('(');
68 if (methodNameEnd == -1) {
69 typeFullName = methodSignature = null;
73 var typeNameEnd = str.LastIndexOf ('.', methodNameEnd);
74 if (typeNameEnd == -1) {
75 typeFullName = methodSignature = null;
79 // Adjustment for Type..ctor ()
80 if (typeNameEnd > 0 && str [typeNameEnd - 1] == '.') {
84 typeFullName = str.Substring (0, typeNameEnd);
85 // Remove generic parameters
86 typeFullName = Regex.Replace (typeFullName, @"\[[^\[\]]*\]", "");
88 methodSignature = str.Substring (typeNameEnd + 1);