cc9b44c91e4c84433198d5d8f10e89c0bf52e83c
[mono.git] / mcs / tools / mono-symbolicate / StackFrameData.cs
1 using System.Text.RegularExpressions;
2 using System.Globalization;
3
4 namespace Mono
5 {
6         class StackFrameData
7         {
8                 static Regex regex = new Regex (@"\w*at (?<Method>.+) *(\[0x(?<IL>.+)\]|<0x.+ \+ 0x(?<NativeOffset>.+)>( (?<MethodIndex>\d+)|)) in <filename unknown>:0");
9
10                 public readonly string TypeFullName;
11                 public readonly string MethodSignature;
12                 public readonly int Offset;
13                 public readonly bool IsILOffset;
14                 public readonly uint MethodIndex;
15                 public readonly string Line;
16
17                 public string File { get; private set; }
18                 public int LineNumber { get; private set; }
19
20                 private StackFrameData (string line, string typeFullName, string methodSig, int offset, bool isILOffset, uint methodIndex)
21                 {
22                         LineNumber = -1;
23
24                         Line = line;
25                         TypeFullName = typeFullName;
26                         MethodSignature = methodSig;
27                         Offset = offset;
28                         IsILOffset = isILOffset;
29                         MethodIndex = methodIndex;
30                 }
31
32                 public static bool TryParse (string line, out StackFrameData stackFrame)
33                 {
34                         stackFrame = null;
35
36                         var match = regex.Match (line);
37                         if (!match.Success)
38                                 return false;
39
40                         string typeFullName, methodSignature;
41                         var methodStr = match.Groups ["Method"].Value.Trim ();
42                         if (!ExtractSignatures (methodStr, out typeFullName, out methodSignature))
43                                 return false;
44
45                         var isILOffset = !string.IsNullOrEmpty (match.Groups ["IL"].Value);
46                         var offsetVarName = (isILOffset)? "IL" : "NativeOffset";
47                         var offset = int.Parse (match.Groups [offsetVarName].Value, NumberStyles.HexNumber, CultureInfo.InvariantCulture);
48
49                         uint methodIndex = 0xffffff;
50                         if (!string.IsNullOrEmpty (match.Groups ["MethodIndex"].Value))
51                                 methodIndex = uint.Parse (match.Groups ["MethodIndex"].Value, CultureInfo.InvariantCulture);
52
53                         stackFrame = new StackFrameData (line, typeFullName, methodSignature, offset, isILOffset, methodIndex);
54
55                         return true;
56                 }
57
58                 static bool ExtractSignatures (string str, out string typeFullName, out string methodSignature)
59                 {
60                         var methodNameEnd = str.IndexOf ('(');
61                         if (methodNameEnd == -1) {
62                                 typeFullName = methodSignature = null;
63                                 return false;
64                         }
65
66                         var typeNameEnd = str.LastIndexOf ('.', methodNameEnd);
67                         if (typeNameEnd == -1) {
68                                 typeFullName = methodSignature = null;
69                                 return false;
70                         }
71
72                         // Adjustment for Type..ctor ()
73                         if (typeNameEnd > 0 && str [typeNameEnd - 1] == '.') {
74                                 --typeNameEnd;
75                         }
76
77                         typeFullName = str.Substring (0, typeNameEnd);
78                         // Remove generic parameters
79                         typeFullName = Regex.Replace (typeFullName, @"\[[^\[\]]*\]", "");
80
81                         methodSignature = str.Substring (typeNameEnd + 1);
82
83                         return true;
84                 }
85
86                 internal void SetLocation (string file, int lineNumber)
87                 {
88                         File = file;
89                         LineNumber = lineNumber;
90                 }
91
92                 public override string ToString () {
93                         if (Line.Contains ("<filename unknown>:0") && LineNumber != -1)
94                                 return Line.Replace ("<filename unknown>:0", string.Format ("{0}:{1}", File, LineNumber));
95
96                         return Line;
97                 }
98         }
99 }