5 using System
.Collections
.Generic
;
8 using Mono
.Collections
.Generic
;
12 public class SymbolManager
17 public SymbolManager (string msymDir
, Logger logger
) {
18 this.msymDir
= msymDir
;
22 internal bool TryResolveLocation (StackFrameData sfData
)
24 if (sfData
.Mvid
== null)
27 var assemblyLocProvider
= GetOrCreateAssemblyLocationProvider (sfData
.Mvid
);
28 if (assemblyLocProvider
== null)
31 SeqPointInfo seqPointInfo
= null;
32 if (!sfData
.IsILOffset
&& sfData
.Aotid
!= null)
33 seqPointInfo
= GetOrCreateSeqPointInfo (sfData
.Aotid
);
35 return assemblyLocProvider
.TryResolveLocation (sfData
, seqPointInfo
);
38 Dictionary
<string, AssemblyLocationProvider
> assemblies
= new Dictionary
<string, AssemblyLocationProvider
> ();
40 private AssemblyLocationProvider
GetOrCreateAssemblyLocationProvider (string mvid
)
42 if (assemblies
.ContainsKey (mvid
))
43 return assemblies
[mvid
];
45 var mvidDir
= Path
.Combine (msymDir
, mvid
);
46 if (!Directory
.Exists (mvidDir
)) {
47 logger
.LogWarning ("MVID directory does not exist: {0}", mvidDir
);
51 string assemblyPath
= null;
52 var exeFiles
= Directory
.GetFiles (mvidDir
, "*.exe");
53 var dllFiles
= Directory
.GetFiles (mvidDir
, "*.dll");
55 if (exeFiles
.Length
+ dllFiles
.Length
!= 1) {
56 logger
.LogError ("MVID directory should include one assembly: {0}", mvidDir
);
60 assemblyPath
= exeFiles
.Length
> 0 ? exeFiles
[0] : dllFiles
[0];
62 var locProvider
= new AssemblyLocationProvider (assemblyPath
, logger
);
64 assemblies
.Add (mvid
, locProvider
);
69 Dictionary
<string, SeqPointInfo
> seqPointInfos
= new Dictionary
<string, SeqPointInfo
> ();
71 private SeqPointInfo
GetOrCreateSeqPointInfo (string aotid
)
73 if (seqPointInfos
.ContainsKey (aotid
))
74 return seqPointInfos
[aotid
];
76 var aotidDir
= Path
.Combine (msymDir
, aotid
);
77 if (!Directory
.Exists (aotidDir
)) {
78 logger
.LogError ("AOTID directory does not exist: {0}", aotidDir
);
82 string msymFile
= null;
83 var msymFiles
= Directory
.GetFiles(aotidDir
, "*.msym");
84 msymFile
= msymFiles
[0];
86 var seqPointInfo
= SeqPointInfo
.Read (msymFile
);
88 seqPointInfos
.Add (aotid
, seqPointInfo
);
93 public void StoreSymbols (params string[] lookupDirs
)
95 foreach (var dir
in lookupDirs
) {
96 var exeFiles
= Directory
.GetFiles (dir
, "*.exe");
97 var dllFiles
= Directory
.GetFiles (dir
, "*.dll");
98 var assemblies
= exeFiles
.Concat (dllFiles
);
99 foreach (var assemblyPath
in assemblies
) {
101 // TODO: Ignore embedded pdb
102 var symbolFile
= GetSymbolFile (assemblyPath
);
104 if (symbolFile
== null) {
105 logger
.LogWarning ("Directory {0} contains {1} but no debug symbols file was found.", dir
, Path
.GetFileName (assemblyPath
));
106 // assemblies without debug symbols are useless
110 var assembly
= AssemblyDefinition
.ReadAssembly (assemblyPath
);
112 var mvid
= assembly
.MainModule
.Mvid
.ToString ("N");
113 var mvidDir
= Path
.Combine (msymDir
, mvid
);
115 if (Directory
.Exists (mvidDir
)) {
117 Directory
.Delete (mvidDir
, true);
118 } catch (DirectoryNotFoundException
) {}
121 Directory
.CreateDirectory (mvidDir
);
123 var mvidAssemblyPath
= Path
.Combine (mvidDir
, Path
.GetFileName (assemblyPath
));
124 File
.Copy (assemblyPath
, mvidAssemblyPath
);
126 var mvidDebugPath
= Path
.Combine (mvidDir
, Path
.GetFileName (symbolFile
));
127 File
.Copy (symbolFile
, mvidDebugPath
);
129 // TODO create MVID dir for non main modules with links to main module MVID
134 static string GetSymbolFile (string assembly
)
136 var pdbName
= Path
.ChangeExtension (assembly
, "pdb");
137 if (File
.Exists (pdbName
))
140 var mdbName
= assembly
+ ".mdb";
142 if (File
.Exists (mdbName
))