1 using System.Text.RegularExpressions;
2 using System.Globalization;
8 static Regex regex = new Regex (@"\w*at (?<Method>.+) *(\[0x(?<IL>.+)\]|<0x.+ \+ 0x(?<NativeOffset>.+)>( (?<MethodIndex>\d+)|)) in <filename unknown>:0");
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;
17 public string File { get; private set; }
18 public int LineNumber { get; private set; }
20 private StackFrameData (string line, string typeFullName, string methodSig, int offset, bool isILOffset, uint methodIndex)
25 TypeFullName = typeFullName;
26 MethodSignature = methodSig;
28 IsILOffset = isILOffset;
29 MethodIndex = methodIndex;
32 public static bool TryParse (string line, out StackFrameData stackFrame)
36 var match = regex.Match (line);
40 string typeFullName, methodSignature;
41 var methodStr = match.Groups ["Method"].Value.Trim ();
42 if (!ExtractSignatures (methodStr, out typeFullName, out methodSignature))
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);
49 uint methodIndex = 0xffffff;
50 if (!string.IsNullOrEmpty (match.Groups ["MethodIndex"].Value))
51 methodIndex = uint.Parse (match.Groups ["MethodIndex"].Value, CultureInfo.InvariantCulture);
53 stackFrame = new StackFrameData (line, typeFullName, methodSignature, offset, isILOffset, methodIndex);
58 static bool ExtractSignatures (string str, out string typeFullName, out string methodSignature)
60 var methodNameEnd = str.IndexOf ('(');
61 if (methodNameEnd == -1) {
62 typeFullName = methodSignature = null;
66 var typeNameEnd = str.LastIndexOf ('.', methodNameEnd);
67 if (typeNameEnd == -1) {
68 typeFullName = methodSignature = null;
72 // Adjustment for Type..ctor ()
73 if (typeNameEnd > 0 && str [typeNameEnd - 1] == '.') {
77 typeFullName = str.Substring (0, typeNameEnd);
78 // Remove generic parameters
79 typeFullName = Regex.Replace (typeFullName, @"\[[^\[\]]*\]", "");
81 methodSignature = str.Substring (typeNameEnd + 1);
86 internal void SetLocation (string file, int lineNumber)
89 LineNumber = lineNumber;
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));