diff options
author | Alexander Köplinger <alex.koeplinger@outlook.com> | 2017-05-19 13:59:00 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-05-19 13:59:00 +0300 |
commit | 3637f8cddf52608a6f7f865ab8e7419c8d98e851 (patch) | |
tree | 70e8c7366877a4ffb7285e88f129f631504dfcbe | |
parent | 087316c833c53a184944558c53caf33c27214b7d (diff) |
[bcl] Dispose Cecil AssemblyDefinition after usage (#4900)
Follow-up to https://github.com/mono/mono/pull/4899. I audited
all the places in BCL where we made use of Cecil's AssemblyDefinition
and made sure we're properly disposing them and not keeping files
unnecessarily open.
I used InMemory=true in cases where tracking the lifetime would
be complicated. There are also some tests in mcs/tests which I
didn't bother to fix.
-rw-r--r-- | mcs/class/Mono.CodeContracts/Mono.CodeContracts.Rewrite/Rewriter.cs | 43 | ||||
-rw-r--r-- | mcs/class/Mono.CodeContracts/Mono.CodeContracts.Static.AST/AssemblyNode.cs | 2 | ||||
-rw-r--r-- | mcs/tools/corcompare/AssemblyResolver.cs | 2 | ||||
-rw-r--r-- | mcs/tools/mdbdump/mdbdump.cs | 7 | ||||
-rw-r--r-- | mcs/tools/mono-symbolicate/LocationProvider.cs | 121 | ||||
-rw-r--r-- | mcs/tools/mono-symbolicate/SymbolManager.cs | 9 | ||||
-rw-r--r-- | mcs/tools/security/permview.cs | 41 |
7 files changed, 116 insertions, 109 deletions
diff --git a/mcs/class/Mono.CodeContracts/Mono.CodeContracts.Rewrite/Rewriter.cs b/mcs/class/Mono.CodeContracts/Mono.CodeContracts.Rewrite/Rewriter.cs index 5654252415d..66fb7f232c0 100644 --- a/mcs/class/Mono.CodeContracts/Mono.CodeContracts.Rewrite/Rewriter.cs +++ b/mcs/class/Mono.CodeContracts/Mono.CodeContracts.Rewrite/Rewriter.cs @@ -67,33 +67,34 @@ namespace Mono.CodeContracts.Rewrite { if (options.Debug && options.WritePdbFile) readerParameters.ReadSymbols = true; - var assembly = this.options.Assembly.IsFilename ? + using (var assembly = this.options.Assembly.IsFilename ? AssemblyDefinition.ReadAssembly (options.Assembly.Filename, readerParameters) : - AssemblyDefinition.ReadAssembly (options.Assembly.Streams.Assembly, readerParameters); + AssemblyDefinition.ReadAssembly (options.Assembly.Streams.Assembly, readerParameters)) { - if (this.options.ForceAssemblyRename != null) { - assembly.Name.Name = this.options.ForceAssemblyRename; - } else if (this.options.OutputFile.IsSet && this.options.OutputFile.IsFilename) { - assembly.Name.Name = Path.GetFileNameWithoutExtension(this.options.OutputFile.Filename); - } + if (this.options.ForceAssemblyRename != null) { + assembly.Name.Name = this.options.ForceAssemblyRename; + } else if (this.options.OutputFile.IsSet && this.options.OutputFile.IsFilename) { + assembly.Name.Name = Path.GetFileNameWithoutExtension(this.options.OutputFile.Filename); + } - var output = this.options.OutputFile.IsSet ? this.options.OutputFile : this.options.Assembly; - var writerParameters = new WriterParameters (); - if (options.WritePdbFile) { - if (!options.Debug) { - return RewriterResults.Error ("Must specify -debug if using -writePDBFile."); + var output = this.options.OutputFile.IsSet ? this.options.OutputFile : this.options.Assembly; + var writerParameters = new WriterParameters (); + if (options.WritePdbFile) { + if (!options.Debug) { + return RewriterResults.Error ("Must specify -debug if using -writePDBFile."); + } + + writerParameters.WriteSymbols = true; } - writerParameters.WriteSymbols = true; - } - - PerformRewrite rewriter = new PerformRewrite (this.options); - rewriter.Rewrite (assembly); + PerformRewrite rewriter = new PerformRewrite (this.options); + rewriter.Rewrite (assembly); - if (output.IsFilename) { - assembly.Write (output.Filename, writerParameters); - } else { - assembly.Write (output.Streams.Assembly, writerParameters); + if (output.IsFilename) { + assembly.Write (output.Filename, writerParameters); + } else { + assembly.Write (output.Streams.Assembly, writerParameters); + } } return new RewriterResults (warnings, errors); diff --git a/mcs/class/Mono.CodeContracts/Mono.CodeContracts.Static.AST/AssemblyNode.cs b/mcs/class/Mono.CodeContracts/Mono.CodeContracts.Static.AST/AssemblyNode.cs index 04c7c6e0bac..adc51def4e2 100644 --- a/mcs/class/Mono.CodeContracts/Mono.CodeContracts.Static.AST/AssemblyNode.cs +++ b/mcs/class/Mono.CodeContracts/Mono.CodeContracts.Static.AST/AssemblyNode.cs @@ -72,7 +72,7 @@ namespace Mono.CodeContracts.Static.AST { public static AssemblyNode ReadAssembly (string filename) { - var readerParameters = new ReaderParameters (); + var readerParameters = new ReaderParameters () { InMemory = true }; AssemblyDefinition definition = AssemblyDefinition.ReadAssembly (filename, readerParameters); return new AssemblyNode (definition); diff --git a/mcs/tools/corcompare/AssemblyResolver.cs b/mcs/tools/corcompare/AssemblyResolver.cs index 56000ca6777..063a688d47a 100644 --- a/mcs/tools/corcompare/AssemblyResolver.cs +++ b/mcs/tools/corcompare/AssemblyResolver.cs @@ -44,7 +44,7 @@ namespace GuiCompare { AssemblyDefinition ProcessFile (string file) { AddSearchDirectory (Path.GetDirectoryName (file)); - var assembly = AssemblyDefinition.ReadAssembly (file, new ReaderParameters { AssemblyResolver = this }); + var assembly = AssemblyDefinition.ReadAssembly (file, new ReaderParameters { AssemblyResolver = this, InMemory = true }); RegisterAssembly (assembly); return assembly; diff --git a/mcs/tools/mdbdump/mdbdump.cs b/mcs/tools/mdbdump/mdbdump.cs index 559bc2b9b3f..4042f07d6b1 100644 --- a/mcs/tools/mdbdump/mdbdump.cs +++ b/mcs/tools/mdbdump/mdbdump.cs @@ -15,10 +15,11 @@ public class MdbDump return 1; } - var assembly = AssemblyDefinition.ReadAssembly (args[0]); + using (var assembly = AssemblyDefinition.ReadAssembly (args[0])) { - var f = MonoSymbolFile.ReadSymbolFile (args[0] + ".mdb"); - DumpSymbolFile (assembly, f, Console.Out); + var f = MonoSymbolFile.ReadSymbolFile (args[0] + ".mdb"); + DumpSymbolFile (assembly, f, Console.Out); + } return 0; } diff --git a/mcs/tools/mono-symbolicate/LocationProvider.cs b/mcs/tools/mono-symbolicate/LocationProvider.cs index f03adfdee58..8a0f6ece91b 100644 --- a/mcs/tools/mono-symbolicate/LocationProvider.cs +++ b/mcs/tools/mono-symbolicate/LocationProvider.cs @@ -11,7 +11,7 @@ namespace Mono { class AssemblyLocationProvider { - AssemblyDefinition assembly; + string assemblyFullPath; Logger logger; public AssemblyLocationProvider (string assemblyPath, Logger logger) @@ -22,85 +22,88 @@ namespace Mono if (!File.Exists (assemblyPath)) throw new ArgumentException ("assemblyPath does not exist: "+ assemblyPath); - var readerParameters = new ReaderParameters { ReadSymbols = true }; - assembly = AssemblyDefinition.ReadAssembly (assemblyPath, readerParameters); + assemblyFullPath = assemblyPath; } public bool TryResolveLocation (StackFrameData sfData, SeqPointInfo seqPointInfo) { - if (!assembly.MainModule.HasSymbols) - return false; + var readerParameters = new ReaderParameters { ReadSymbols = true }; + using (var assembly = AssemblyDefinition.ReadAssembly (assemblyFullPath, readerParameters)) { - TypeDefinition type = null; - string[] nested; - if (sfData.TypeFullName.IndexOf ('/') >= 0) - nested = sfData.TypeFullName.Split ('/'); - else - nested = sfData.TypeFullName.Split ('+'); - - var types = assembly.MainModule.Types; - foreach (var ntype in nested) { - if (type == null) { - // Use namespace first time. - type = types.FirstOrDefault (t => t.FullName == ntype); - } else { - type = types.FirstOrDefault (t => t.Name == ntype); + if (!assembly.MainModule.HasSymbols) + return false; + + TypeDefinition type = null; + string[] nested; + if (sfData.TypeFullName.IndexOf ('/') >= 0) + nested = sfData.TypeFullName.Split ('/'); + else + nested = sfData.TypeFullName.Split ('+'); + + var types = assembly.MainModule.Types; + foreach (var ntype in nested) { + if (type == null) { + // Use namespace first time. + type = types.FirstOrDefault (t => t.FullName == ntype); + } else { + type = types.FirstOrDefault (t => t.Name == ntype); + } + + if (type == null) { + logger.LogWarning ("Could not find type: {0}", ntype); + return false; + } + + types = type.NestedTypes; } - if (type == null) { - logger.LogWarning ("Could not find type: {0}", ntype); + var parensStart = sfData.MethodSignature.IndexOf ('('); + var methodName = sfData.MethodSignature.Substring (0, parensStart).TrimEnd (); + var methodParameters = sfData.MethodSignature.Substring (parensStart); + var methods = type.Methods.Where (m => CompareName (m, methodName) && CompareParameters (m.Parameters, methodParameters)).ToArray (); + if (methods.Length == 0) { + logger.LogWarning ("Could not find method: {0}", methodName); + return false; + } + if (methods.Length > 1) { + logger.LogWarning ("Ambiguous match for method: {0}", sfData.MethodSignature); return false; } + var method = methods [0]; - types = type.NestedTypes; - } + int ilOffset; + if (sfData.IsILOffset) { + ilOffset = sfData.Offset; + } else { + if (seqPointInfo == null) + return false; - var parensStart = sfData.MethodSignature.IndexOf ('('); - var methodName = sfData.MethodSignature.Substring (0, parensStart).TrimEnd (); - var methodParameters = sfData.MethodSignature.Substring (parensStart); - var methods = type.Methods.Where (m => CompareName (m, methodName) && CompareParameters (m.Parameters, methodParameters)).ToArray (); - if (methods.Length == 0) { - logger.LogWarning ("Could not find method: {0}", methodName); - return false; - } - if (methods.Length > 1) { - logger.LogWarning ("Ambiguous match for method: {0}", sfData.MethodSignature); - return false; - } - var method = methods [0]; + ilOffset = seqPointInfo.GetILOffset (method.MetadataToken.ToInt32 (), sfData.MethodIndex, sfData.Offset); + } - int ilOffset; - if (sfData.IsILOffset) { - ilOffset = sfData.Offset; - } else { - if (seqPointInfo == null) + if (ilOffset < 0) return false; - ilOffset = seqPointInfo.GetILOffset (method.MetadataToken.ToInt32 (), sfData.MethodIndex, sfData.Offset); - } + if (!method.DebugInformation.HasSequencePoints) + return false; - if (ilOffset < 0) - return false; + SequencePoint prev = null; + foreach (var sp in method.DebugInformation.SequencePoints.OrderBy (l => l.Offset)) { + if (sp.Offset >= ilOffset) { + sfData.SetLocation (sp.Document.Url, sp.StartLine); + return true; + } - if (!method.DebugInformation.HasSequencePoints) - return false; + prev = sp; + } - SequencePoint prev = null; - foreach (var sp in method.DebugInformation.SequencePoints.OrderBy (l => l.Offset)) { - if (sp.Offset >= ilOffset) { - sfData.SetLocation (sp.Document.Url, sp.StartLine); + if (prev != null) { + sfData.SetLocation (prev.Document.Url, prev.StartLine); return true; } - prev = sp; - } - - if (prev != null) { - sfData.SetLocation (prev.Document.Url, prev.StartLine); - return true; + return false; } - - return false; } static bool CompareName (MethodDefinition candidate, string expected) diff --git a/mcs/tools/mono-symbolicate/SymbolManager.cs b/mcs/tools/mono-symbolicate/SymbolManager.cs index a204788306b..eb06043a823 100644 --- a/mcs/tools/mono-symbolicate/SymbolManager.cs +++ b/mcs/tools/mono-symbolicate/SymbolManager.cs @@ -107,10 +107,11 @@ namespace Mono continue; } - var assembly = AssemblyDefinition.ReadAssembly (assemblyPath); - - var mvid = assembly.MainModule.Mvid.ToString ("N"); - var mvidDir = Path.Combine (msymDir, mvid); + string mvidDir; + using (var assembly = AssemblyDefinition.ReadAssembly (assemblyPath)) { + var mvid = assembly.MainModule.Mvid.ToString ("N"); + mvidDir = Path.Combine (msymDir, mvid); + } if (Directory.Exists (mvidDir)) { try { diff --git a/mcs/tools/security/permview.cs b/mcs/tools/security/permview.cs index 422de82f621..257a814925b 100644 --- a/mcs/tools/security/permview.cs +++ b/mcs/tools/security/permview.cs @@ -375,28 +375,29 @@ namespace Mono.Tools { return 0; string assemblyName = args [args.Length - 1]; - AssemblyDefinition ad = AssemblyDefinition.ReadAssembly (assemblyName); - if (ad != null) { - bool complete = false; - - if (declarative) { - // full output (assembly+classes+methods) - complete = ProcessAssemblyComplete (tw, ad); - } else if (xmloutput) { - // full output in XML (for easier diffs after c14n) - complete = ProcessAssemblyXml (tw, ad); - } else { - // default (assembly only) - complete = ProcessAssemblyOnly (tw, ad); - } + using (AssemblyDefinition ad = AssemblyDefinition.ReadAssembly (assemblyName)) { + if (ad != null) { + bool complete = false; + + if (declarative) { + // full output (assembly+classes+methods) + complete = ProcessAssemblyComplete (tw, ad); + } else if (xmloutput) { + // full output in XML (for easier diffs after c14n) + complete = ProcessAssemblyXml (tw, ad); + } else { + // default (assembly only) + complete = ProcessAssemblyOnly (tw, ad); + } - if (!complete) { - Console.Error.WriteLine ("Couldn't reflect informations."); - return 1; + if (!complete) { + Console.Error.WriteLine ("Couldn't reflect informations."); + return 1; + } + } else { + Console.Error.WriteLine ("Couldn't load assembly '{0}'.", assemblyName); + return 2; } - } else { - Console.Error.WriteLine ("Couldn't load assembly '{0}'.", assemblyName); - return 2; } tw.Close (); } |