[System] EndRead now throws WebException on abort.
[mono.git] / mcs / tools / mono-symbolicate / symbolicate.cs
1 using System;
2 using System.IO;
3 using System.Globalization;
4 using System.Text.RegularExpressions;
5
6 namespace Symbolicate
7 {
8         public class Program
9         {
10                 static Regex regex = new Regex (@"\w*at (?<Method>.+) *(\[0x(?<IL>.+)\]|<0x.+ \+ 0x(?<NativeOffset>.+)>( (?<MethodIndex>\d+)|)) in <filename unknown>:0");
11
12                 public static int Main (String[] args)
13                 {
14                         if (args.Length < 2) {
15                                 Console.Error.WriteLine ("Usage: symbolicate <assembly path> <input file> [lookup directories]");
16                                 return 1;
17                         }
18
19                         var assemblyPath = args [0];
20                         var inputFile = args [1];
21
22                         var locProvider = new LocationProvider ();
23
24                         for (var i = 2; i < args.Length; i++)
25                                 locProvider.AddDirectory (args [i]);
26
27                         locProvider.AddAssembly (assemblyPath);
28
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);
33                             }
34                         }
35
36                         return 0;
37                 }
38
39                 static string SymbolicateLine (string line, LocationProvider locProvider)
40                 {
41                         var match = regex.Match (line);
42                         if (!match.Success)
43                                 return line;
44
45                         string typeFullName, methodSignature;
46                         var methodStr = match.Groups ["Method"].Value.Trim ();
47                         if (!ExtractSignatures (methodStr, out typeFullName, out methodSignature))
48                                 return line;
49
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);
53
54                         uint methodIndex = 0xffffff;
55                         if (!string.IsNullOrEmpty (match.Groups ["MethodIndex"].Value))
56                                 methodIndex = uint.Parse (match.Groups ["MethodIndex"].Value, CultureInfo.InvariantCulture);
57
58                         var loc = locProvider.TryGetLocation (typeFullName, methodSignature, offset, isOffsetIL, methodIndex);
59                         if (loc == null)
60                                 return line;
61
62                         return line.Replace ("<filename unknown>:0", string.Format ("{0}:{1}", loc.Document.Url, loc.StartLine));
63                 }
64
65                 static bool ExtractSignatures (string str, out string typeFullName, out string methodSignature)
66                 {
67                         var methodNameEnd = str.IndexOf ('(');
68                         if (methodNameEnd == -1) {
69                                 typeFullName = methodSignature = null;
70                                 return false;
71                         }
72
73                         var typeNameEnd = str.LastIndexOf ('.', methodNameEnd);
74                         if (typeNameEnd == -1) {
75                                 typeFullName = methodSignature = null;
76                                 return false;
77                         }
78
79                         // Adjustment for Type..ctor ()
80                         if (typeNameEnd > 0 && str [typeNameEnd - 1] == '.') {
81                                 --typeNameEnd;
82                         }
83
84                         typeFullName = str.Substring (0, typeNameEnd);
85                         // Remove generic parameters
86                         typeFullName = Regex.Replace (typeFullName, @"\[[^\[\]]*\]", "");
87
88                         methodSignature = str.Substring (typeNameEnd + 1);
89                         return true;
90                 }
91         }
92 }