在Delphi中:如何在调试时跳过部分代码?
在Delphi中调试时,我经常无意地进入我不感兴趣的代码。
让我们首先说,我知道您可以使用F8,并且可以使用f4运行到特定的行。
示例:
function TMyClass.DoStuff():Integer; begin // do some stuff bla(); end; procedure TMyClass.Foo() begin if DoStuff()=0 then // press F7 when entering this line beep; end;
示例:我想通过按下DoStuff()来进入方法F7 (),但是我首先没有使用FastMM4.FastGetMem(),这是一个大量的汇编代码,显然我目前对它并不感兴趣。
有几种方法可以解决这一问题,但我不喜欢其中任何一种:
- 在"bla“上添加一个断点(如果您只想在特殊情况下(如迭代23498938)进入DoStuff,几乎毫无用处);
- 而不是按F7,手动将光标移动到"bla",然后按F4 (对于这个简单的例子来说是有效的)。在实践中,它没有);
- 在fastmm的情况下:暂时禁用紧固件;
有什么方法可以提示IDE说我是
我希望得到一些神奇的编译器指令,比如{$NODEBUG BEGIN/END}或类似的东西。
在大多数情况下,能够排除整个单元对我来说已经足够细粒度了,但是能够避免某些方法甚至代码行会更好。
更新:也许码器应该引入类似跳过点(而不是断点)的东西:-)
有一个“神奇的不调试开关”。{$D-}将禁用调试代码的生成。将其放置在您的FastMM单元的顶部,您将不会最终跟踪到它。如果你真的在一个你不想加入的函数中结束,SHIFT-F8会很快地把你弄出来。(警告:不要在运行堆栈的程序集代码例程中使用SHIFT-F8。不可预测的行为会导致。) F4到其底部。)
如果您正在跳转FastMM代码,那么就会发生内存操作。您显示的代码没有任何内存操作,所以您的问题是不完整的。我来猜猜你的意思。
当子例程有编译器托管类型的局部变量(例如字符串、接口或动态数组)时,函数序言有一些重要的工作要做。序言也是调整输入参数的参考计数的地方。调试器表示函数的begin
行中的序言。如果当前的执行点是该行,并且您“跨入”行,您将被带到RTL代码中来管理特殊类型。(我也不认为FastMM会参与其中,但也许事情已经改变了。)在这种情况下,一件容易的事情是“跨过”begin
行,而不是进入它;使用F8。
如果您在输入突出显示的行时确实按了F7,那么您就做错了。这是进入begin
行,而不是调用DoStuff
的行。因此,您是否被带到FastMM代码与DoStuff
的实现无关。要调试对DoStuff
的调用,当前的执行点应该已经是调用的行。
如果只想在迭代23498938中调试DoStuff
,那么可以在该函数中设置条件断点。在沟槽中单击以形成一个正常的断点,然后右击它以显示其属性。在这里,您可以定义一个条件,每次执行到该点时都会对其进行评估。只有在条件为真时,调试器才会停止。按F8以“跨过”DoStuff
调用,如果条件为真,调试器就会停止,就好像您按了F7一样。
您可以切换“使用调试DCU”选项,以避免进入大多数RTL和VCL单元。我不知道FastMM是否包含在那个集合中。关键的区别在于您链接到的DCU是否带有调试信息。设置更改库路径以包括或排除调试DCU所在的子目录。我认为您可以配置包含或排除的调试目录集,以便根据“调试DCU”设置添加或删除自定义目录集。
回到断点。可以通过为断点指定名称来设置断点组。您可以使用高级断点在传递时启用或禁用一组指定的断点。(如果需要,断点组只能有一个断点。)因此,例如,如果您也通过了程序中的其他位置Y,则如果您只想在X位置中断,您可以在X设置一个禁用的断点,在Y设置一个非中断断点。将“启用组”设置为启用组X。
您还可以利用禁用的断点而不自动启用和禁用。您的断点出现在“断点”调试器窗口中。如果您正在遍历DoStuff
,并且决定这次要检查bla
,请转到断点窗口并在bla
上启用断点。不需要导航到bla
的实现来设置断点。
有关高级断点的更多信息,请参见在Delphi中使用非断点和几年前由Cary Jensen撰写的文章。
我可能在您的帖子中遗漏了一些东西,但是使用FastMM4,您可以编辑FastMM4Options.Inc包含文件并删除'.‘。根据以下定义:
来自FastMM4Options.inc *
{启用此选项可禁止生成FastMM4.pas单元的调试信息。这将防止集成调试器进入内存管理器代码。
{$.define NoDebugInfo}
当重新编译(可能需要构建)时,调试器将(应该)不再调试FastMM代码。
使用预编译的非调试DCU的FasmMM
在项目dpr文件中,我使用
uses {$IFNDEF DEBUG} FastMM4, {$ENDIF} ... // other units
若要在调试模式下排除FastMM4,请执行以下操作。不需要更改FastMM4,因此在更改为不同版本时,不必记住在FastMM中添加{$D-}。
AFAIK,调试器只知道您可以在选项中修改的浏览路径中的文件。因此,如果您排除模块的路径,您对调试不感兴趣,这将产生您想要做的事情的效果。
注意:代码完成也依赖于浏览路径,因此您可能会遇到需要时代码完成不足的情况。
虽然这不是对您的问题的直接回答,但是您可以修改第一个建议的解决方案,方法是将断点放在bla上,只有在Foo处的断点被传递时才启用该断点(或者您选择的其他条件,例如迭代计数)。只有当你想要的时候它才会破裂。
顺便说一句,我越来越多地发现,我不是在断点停止执行,而是将变量值或堆栈转储转储到消息日志中。这允许更仔细的分析比现场检查变量等FWIW.
不是的。我不相信有一种方法可以告诉调试器永远不要停止在某个部分的代码。没有魔法指令。
当你进入一个你不想进入的例程时,你能做的最好的事情就是使用Shift+F8,它会一直运行到返回。然后执行F7或F8退出过程。
嗯。现在我看到梅森的答案了。学到了一些东西。谢了梅森。+1