在Visual Studio中,是否有任何方法可以在输入某个文件(或类)时使调试器中断?请不要回答"只是在每个方法的开头设置一个断点":)
我正在使用C#.
宏可以成为你的朋友.这是一个宏,它将为当前类中的每个方法添加一个断点(在运行之前将光标放在类中的某个位置).
Public Module ClassBreak Public Sub BreakOnAnyMember() Dim debugger As EnvDTE.Debugger = DTE.Debugger Dim sel As EnvDTE.TextSelection = DTE.ActiveDocument.Selection Dim editPoint As EnvDTE.EditPoint = sel.ActivePoint.CreateEditPoint() Dim classElem As EnvDTE.CodeElement = editPoint.CodeElement(vsCMElement.vsCMElementClass) If Not classElem Is Nothing Then For Each member As EnvDTE.CodeElement In classElem.Children If member.Kind = vsCMElement.vsCMElementFunction Then debugger.Breakpoints.Add(member.FullName) End If Next End If End Sub End Module
编辑:更新为按功能名称添加断点,而不是文件/行号.它"感觉"更好,并且在断点窗口中更容易识别.
您可以从介绍某种面向方面的编程开始 - 例如参见 此解释 - 然后在单个OnEnter方法中添加断点.
根据您选择的AOP框架,它需要在您的代码中进行一些修饰并引入一些开销(您可以稍后删除),但至少您不需要在任何地方设置断点.在某些框架中,您甚至可以在没有代码更改的情况下引入它,只是侧面的XML文件?
也许你可以使用像PostSharp这样的AOP框架在输入方法时进入调试器.看一下这个页面上非常简短的教程,举例说明如何在输入方法时记录/跟踪.
您可以将Debugger.Break()语句放入OnEntry-handler中,而不是记录.虽然,调试器不会在你的方法中停止,但在OnEntry-handler中(所以我不确定这是否真的有帮助).
这是一个非常基本的样本:
Aspect类定义了一个OnEntry处理程序,它调用Debugger.Break():
[Serializable] public sealed class DebugBreakAttribute : PostSharp.Laos.OnMethodBoundaryAspect { public DebugBreakAttribute() {} public DebugBreakAttribute(string category) {} public string Category { get { return "DebugBreak"; } } public override void OnEntry(PostSharp.Laos.MethodExecutionEventArgs eventArgs) { base.OnEntry(eventArgs); // debugger will break here. Press F10 to continue to the "real" method System.Diagnostics.Debugger.Break(); } }
然后,我可以将此方面应用于我的类,我希望调用器在调用方法时中断:
[DebugBreak("DebugBreak")] public class MyClass { public MyClass() { // ... } public void Test() { // ... } }
现在,如果我构建并运行应用程序,只要调用MyClass的某个方法,调试器就会在OnEntry()处理程序中停止.我所要做的就是按F10,我就是MyClass的方法.
好吧,正如大家所说,它涉及在每个方法的开头设置一个断点.但你没有看到更大的图景.
为了使其工作,必须在每个方法的开头设置断点.无论是手动执行还是调试器自动执行,都必须设置这些断点才能使其正常工作.
所以,问题确实变成了,"如果有足够的需要这个功能,那么值得在调试器中构建一个自动设置所有断点的方法吗?".答案是,"不是真的".
此功能在VS中实现,用于本机C++.crtl-B并将'function'指定为"Classname ::*",这会在类的每个方法的开头设置一个断点.断点集在断点窗口(ctrl-alt-B)中组合在一起,因此可以将它们作为一组启用,禁用和删除.
遗憾的是,宏可能是托管代码的最佳选择.
这在WinDbg中工作正常:
bm exename!CSomeClass::*
(只是为了澄清,上面的行设置了类中所有函数的断点,就像OP要求的那样,而不是诉诸CRT黑客攻击或宏观愚蠢)