[mono-symbolicate] Adds store-symbols
[mono.git] / mcs / tools / mono-symbolicate / symbolicate.cs
1 using System;
2 using System.IO;
3 using System.Text;
4 using System.Linq;
5 using System.Collections.Generic;
6 using System.Globalization;
7
8 namespace Mono
9 {
10         public class Symbolicate
11         {
12                 public static int Main (String[] args)
13                 {
14                         if (args.Length != 2 && (args[0] == "store-symbols" && args.Length < 3)) {
15                                 Console.Error.WriteLine ("Usage: symbolicate <msym dir> <input file>");
16                                 Console.Error.WriteLine ("       symbolicate store-symbols <msym dir> [<dir>]+");
17                                 return 1;
18                         }
19
20                         if (args[0] == "store-symbols") {
21                                 var msymDir = args[1];
22                                 var lookupDirs = args.Skip (1).ToArray ();
23
24                                 var symbolManager = new SymbolManager (msymDir);
25
26                                 symbolManager.StoreSymbols (lookupDirs);
27
28                         } else {
29                                 var msymDir = args [0];
30                                 var inputFile = args [1];
31
32                                 var symbolManager = new SymbolManager (msymDir);
33
34                                 using (StreamReader r = new StreamReader (inputFile)) {
35                                         var sb = Process (r, symbolManager);
36                                         Console.Write (sb.ToString ());
37                                 }
38                         }
39
40                         return 0;
41                 }
42
43                 public static StringBuilder Process (StreamReader reader, SymbolManager symbolManager)
44                 {
45                         List<StackFrameData> stackFrames = new List<StackFrameData>();
46                         List<StackTraceMetadata> metadata = new List<StackTraceMetadata>();
47                         StringBuilder sb = new StringBuilder ();
48                         bool linesEnded = false;
49
50                         for (var line = reader.ReadLine (); line != null; line = reader.ReadLine ()) {
51                                  {
52                                         StackFrameData sfData;
53                                         if (!linesEnded && StackFrameData.TryParse (line, out sfData)) {
54                                                 stackFrames.Add (sfData);
55                                                 continue;
56                                         }
57                                         linesEnded = true;
58                                 } 
59
60                                 if (stackFrames.Count > 0) {
61                                         {
62                                                 StackTraceMetadata stMetadata;
63                                                 if (StackTraceMetadata.TryParse (line, out stMetadata)) {
64                                                         metadata.Add (stMetadata);
65                                                         continue;
66                                                 }
67                                         }
68
69                                         string aotid = null;
70                                         var aotidMetadata = metadata.FirstOrDefault ( m => m.Id == "AOTID" );
71                                         if (aotidMetadata != null)
72                                                 aotid = aotidMetadata.Value;
73
74                                         var linesMvid = ProcessLinesMVID (metadata);
75                                         var lineNumber = 0;
76                                         foreach (var sfData in stackFrames) {
77                                                 string mvid = null;
78                                                 if (linesMvid.ContainsKey (lineNumber))
79                                                         mvid = linesMvid [lineNumber++];
80
81                                                 symbolManager.TryResolveLocation (sfData, mvid, aotid);
82
83                                                 sb.AppendLine (sfData.ToString ());
84                                         }
85
86                                         foreach (var m in metadata)
87                                                 sb.AppendLine (m.Line);
88                                         
89                                         // Clear lists for next stack trace
90                                         stackFrames.Clear ();
91                                         metadata.Clear ();
92                                 }
93
94                                 linesEnded = false;
95
96                                 // Append last line
97                                 sb.AppendLine (line);
98                         }
99
100                         return sb;
101                 }
102
103                 private static Dictionary<int, string> ProcessLinesMVID (List<StackTraceMetadata> metadata)
104                 {
105                         var linesMvid = new Dictionary<int, string> ();
106                         var mvidData = metadata.Where ( m => m.Id == "MVID" ).Select ( m => m.Value );
107                         foreach (var m in mvidData) {
108                                 var s1 = m.Split (new char[] {' '}, 2);
109                                 var mvid = s1 [0];
110                                 var lines = s1 [1].Split (',');
111                                 foreach (var line in lines)
112                                         linesMvid.Add (int.Parse (line), mvid);
113                         }
114
115                         return linesMvid;
116                 }
117         }
118 }