如何在 codedom 编译的代码中调试/中断
Posted
技术标签:
【中文标题】如何在 codedom 编译的代码中调试/中断【英文标题】:How to debug/break in codedom compiled code 【发布时间】:2010-10-26 22:03:15 【问题描述】:我有一个动态加载 c# 源文件并将它们作为插件运行的应用程序。当我在调试模式下运行主应用程序时,是否可以调试到动态程序集中?显然设置断点是有问题的,因为源不是原始项目的一部分,但我应该能够进入或中断代码的异常吗?
有没有办法让 codedom 为这个或其他东西生成 PDB?
这是我用于动态编译的代码。
CSharpCodeProvider codeProvider = new CSharpCodeProvider(new Dictionary<string, string>() "CompilerVersion", "v3.5" );
//codeProvider.
ICodeCompiler icc = codeProvider.CreateCompiler();
CompilerParameters parameters = new CompilerParameters();
parameters.GenerateExecutable = false;
parameters.GenerateInMemory = true;
parameters.CompilerOptions = string.Format("/lib:\"0\"", Application.StartupPath);
parameters.ReferencedAssemblies.Add("System.dll");
parameters.ReferencedAssemblies.Add("System.Core.dll");
CompilerResults results = icc.CompileAssemblyFromSource(parameters, Source);
DLL.CreateInstance(t.FullName, false, BindingFlags.Default, null, new object[] engine , null, null);
【问题讨论】:
出于好奇(我从来没有真正弄乱过 CodeDom 的东西)如果你尝试放置 System.Diagnostics.Debugger.Break(); 会发生什么?在你的代码的某个地方?那你能进去吗? 这行得通,但仅限于接受答案中的选项。 我无意中重复了这个问题(codedom 不是我寻找的关键)。 ***.com/questions/1593920/…。我添加了一个涉及接口的解决方案。希望对您有所帮助... 【参考方案1】:尝试以下选项:
parameters.GenerateInMemory = false; //default
parameters.TempFiles = new TempFileCollection(Environment.GetEnvironmentVariable("TEMP"), true);
parameters.IncludeDebugInformation = true;
我不确定这在您的情况下是否可以正常工作,但如果可以,您可以使用条件编译指令将此参数括起来,以便它仅在调试模式下转储生成的程序集。
【讨论】:
2.42 年过去了,但先生,你太棒了! 它节省了我找出问题的时间:) 11年过去了,这个信息还是纯金的。谢谢!【参考方案2】:answer by @bbmud 是正确的,尽管它错过了一个错误修复。 CSharpCodeGenerator(.NET 中将 C# 代码编译为 IL 的类)设置为在创建 pdb 文件后立即删除它们,除非您将 /debug:pdbonly
添加到 CompilerOptions 字符串。但是,如果您这样做,IncludeDebugInformation
标志将被忽略,编译器会生成难以调试的优化代码。为避免这种情况,您必须明确告诉代码生成器保留所有文件。
这是完整的食谱:
parameters.GenerateInMemory = false; //default
parameters.TempFiles = new TempFileCollection(Environment.GetEnvironmentVariable("TEMP"), true);
parameters.IncludeDebugInformation = true;
parameters.TempFiles.KeepFiles = true
这是CSharpCodeGenerator代码的罪魁祸首:
string fileExtension = "pdb";
if ((options.CompilerOptions != null) && (CultureInfo.InvariantCulture.CompareInfo.IndexOf(options.CompilerOptions, "/debug:pdbonly", CompareOptions.IgnoreCase) != -1))
results.TempFiles.AddExtension(fileExtension, true);
else
results.TempFiles.AddExtension(fileExtension);
TempFiles.AddExtension(fileExtension, true)
告诉编译器保留 pdb 文件。 results.TempFiles.AddExtension(fileExtension);
的 else 选项告诉它将 pdb 视为所有临时文件,默认情况下意味着删除它们。
【讨论】:
TempFileCollection
中的第二个参数(名为“keepFiles”)已经将 KeepFiles
属性设置为 true。 (或者至少在 .NET 4.0 中是这样的)以上是关于如何在 codedom 编译的代码中调试/中断的主要内容,如果未能解决你的问题,请参考以下文章