可以从调试器停止并继续执行吗?

Posted

技术标签:

【中文标题】可以从调试器停止并继续执行吗?【英文标题】:Stop and continue execution from debugger possible? 【发布时间】:2010-07-17 17:30:29 【问题描述】:

有什么方法可以像 ctrl+c 那样从调试器中停止执行 matlab 程序,但随后能够继续执行(就像你可以在 c# 中说的那样)?

如果没有,除了尝试在您的 matlab 代码中预先设置断点或 dbstop 语句之外,还有什么更好的解决方法吗?

我希望能够中断长时间运行的模拟以查看当前状态,然后继续模拟。

我目前正在使用/考虑的两个选项是

    代码中的 dbstop 命令(或(条件)断点)。 缺点是有时我不想停止模拟几个小时,有时只想在几秒钟后停止(我不一定提前知道),这不适用于这种方法:如果我将中断条件设置为每 5 分钟中断一次,我不能让 matlab 在没有交互的情况下运行数小时。如果我将条件设置为更高,我必须等待太长时间才能达到条件。

    包含每隔几秒/分钟保存工作空间并将工作空间导入第二个 matlab 实例的代码。缺点是这是一个巨大的麻烦,也不一定允许我使用已保存工作区的状态恢复模拟,然后逐步执行代码进行几次迭代。

我希望有比这两个更好的解决方案。感谢您的任何建议!

编辑:我想我要做的是编写简单的 matlab 函数,该函数在每次迭代时检查环境变量或磁盘上的文件,如果我在此文件中设置标志或调用 dbstop环境。这样,我可以通过编辑文件来控制断点何时(以及如果需要的话)从外部 matlab 命中。凌乱,但应该工作。

【问题讨论】:

或许你可以试试条件断点 感谢 Amro,但条件断点/dbstops 是我在选项 1 中所做的,我也许应该编辑问题以使其更清楚。不幸的是,这对我来说根本不是一个理想的解决方案,这就是为什么我希望有更好的选择 哦,我刚刚看了你的编辑,正是我的想法.. 【参考方案1】:

这不一定是最好的方法,但您可以模拟基于文件的信号/中断框架。这可以通过在长模拟循环中每隔一段时间检查一次特定文件的存在来完成。如果是,则使用keyboard 命令进入交互模式。

类似的东西:

CHECK_EVERY = 10;    %# like a polling rate

tic
i = 1;               %# loop counter
while true           %# long running loop
    if rem(i,CHECK_EVERY) == 0 && exist('debug.txt','file')
        fprintf('%f seconds since last time.\n', toc)
        keyboard
        tic
    end

    %# ... long calculations ...    

    i = i + 1;
end

您将像往常一样运行模拟。当您想单步执行代码时,只需创建一个文件debug.txt(手动),执行将停止并得到提示:

2.803095 seconds since last time.
K>> 

然后您可以像往常一样检查您的变量...要继续,只需运行return(不要忘记临时重命名或删除文件)。要退出,请使用dbquit


编辑:我刚刚想到,与其检查文件,更简单的解决方案是使用虚拟图形作为标志(只要图形打开,继续运行)。

hFig = figure; drawnow
while true
    if ~ishandle(hFig)
        keyboard
        hFig = figure; drawnow
    end

    %# ...
    pause(0.5)
end

【讨论】:

我实际上只是在考虑也许可以按照这些思路做一些事情:) 可能会尽可能好。谢谢! @BenSchwehn:idea = 使用虚拟人物而不是外部文件 我喜欢这个人物的想法!在命令行上运行时不起作用,但在命令行上我很少想调试。很好,谢谢! 这是在 MATLAB 中实现这一目标的唯一实用方法,这有点荒谬,但感谢您提供了一个很好的 hack 和完美工作的解决方案!【参考方案2】:

使用release of R2016a,您只需点击代码编辑器中的暂停按钮,它就会立即停止。键盘快捷键是Ctrl+F5。

要在程序运行时暂停程序的执行,请在编辑器选项卡中单击暂停按钮。 MATLAB 在下一个可执行行暂停执行*。

当您的代码运行时,开始按钮将变为暂停:

此版本的另一个变化是能够在运行时添加/删除断点。显然,以前你不能这样做。

【讨论】:

我会在几个小时内删除它,但我只是想就 accumarray 的成功案例与您联系。 OP 的代码运行了 10 分钟,当我建议 accumarray 时,运行时间缩短到 2 秒:D。 ***.com/questions/38067363/… - 上个月我实际上在你附近几次......采访。我应该记得联系你。哎呀:(也许下一次。希望一切都好! 请注意文档中的pauses execution at the next executable line 注释,这意味着如果您正在执行的当前命令需要2 小时才能完成,Matlab 将在2 小时后停止。它不像 Visual Studio,您可以在程序中的下一条 CPU 指令处停止。【参考方案3】:

您可以在 MATLAB 编辑器中设置 conditional breakpoint。您也可以使用DBSTOP 来执行此操作。例如,这将在文件 myFcn 的第 20 行设置一个条件断点,当循环变量 i 是 500 的倍数时将停止执行:

dbstop in myFcn.m at 20 if rem(i,500) == 0

然后您可以在检查一些变量后continue execution。

【讨论】:

谢谢,这几乎就是我在问题选项 1 中所做的。但正如我所说,这有一个缺点,我不知道在多少分钟后我想先验地停止。即如果条件中的 500 对应于 5 分钟的执行,我不能简单地让模拟运行几个小时,而必须每 5 分钟与 matlab 交互一次,否则模拟会停止。相反,如果我将 500 更改为 5000(50 分钟运行时间),我必须等待 50 分钟,直到 matlab 第一次停止...【参考方案4】:

如果将工作空间保存到文件中可以很好地满足您的需求,那么使用切换按钮制作一个简单的 GUI 怎么样。在您的代码中,检查按钮的状态。如果按下按钮,则保存状态,更新静态文本以反映上次保存的时间戳,然后取消按下按钮。或者,根据该切换按钮的状态设置条件断点。

【讨论】:

【参考方案5】:

这是使用waitinput File Exchange submission 的替代解决方案。 优点是您可以在当前会话中使用它,或者在设置文件很麻烦的情况下使用它。也不会在电脑上留下文件。

不幸的是,缺点也存在,您需要等待检查时刻才能终止,这会花费一些时间。

for t = 1:10
    pause(3) %Doing some calculations
    str = waitinput('Enter 1 if you want to stop ',5);
    if ~isnan(str)
        keyboard; % Enter dbcont if you want to continue from here
    end
    ['moving on, it is now: ' datestr(now)]
    pause(3) %Doing some more calculations
end

如果需要,您可以阻止将行打印到屏幕上。在这种情况下,您需要在图形窗口打开时输入输入(查看窗口上的开始栏)。

总而言之,您可以放置​​在条件断点之类的地方的短代码是:

if ~isnan(waitinput('',5))
    keyboard; 
end

【讨论】:

【参考方案6】:

在某个版本之后(我不知道具体是哪一个):

Windows:Ctrl + F5 Mac:Command + F5(我猜) Unix:我也在寻找答案

2016a之后,界面上也有一个按钮。

【讨论】:

以上是关于可以从调试器停止并继续执行吗?的主要内容,如果未能解决你的问题,请参考以下文章

python解释器:中断并继续

如何在GDB中调试多线程程序时一次继续一个线程?

Xcode 11 断点仅在 HEX 代码上停止

vs2010 调试快捷键

GDB 调试多线程程序的总结

PhpStorm 本地调试停止工作 - 您在设置中看到问题吗?