如何在 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 编译的代码中调试/中断的主要内容,如果未能解决你的问题,请参考以下文章

GDB:断点没有被命中

CodeDOM 系列一: 初识

C# CodeDom 编译器。错误 CS1056:意外字符“$”

动态源代码生成和编译

在文本框中编译代码并保存到exe

如何在keil调试中黄色箭头不出现汇编窗口而是停在main主函数上