如何检测程序陷入无限循环的位置?

发布于 2024-11-24 02:38:12 字数 631 浏览 4 评论 0原文

我正在开发一款(相对复杂的)游戏。游戏在发布模式下冻结。 1-2 分钟后就会冻结。的游戏玩法。我所拥有的发布模式的当前配置允许我中断(即进入调试),这很好,但可能会给我错误的信息,但这对于这种特殊情况来说很好(我可以关闭单个优化)文件/函数/代码)。

问题是,我(我们,因为我们是一个团队)不知道它挂在哪里。它并不像一个相对较小的无限循环挂起那么简单,因为其他东西(图形、声音)正在更新,只是游戏玩法已经停滞了。主游戏循环(无限循环)始终在运行,并且非常长/复杂,因此单步执行将是一种痛苦(但它是选项之一)。

我尝试的第一件事是 Visual Studio 的 break all,但它总是会中断不属于我的代码,从而向我显示程序集输出。最终,只要有足够的毅力,SVN 历史记录检查和注释代码我将能够找出它挂在哪里,但必须有更好的方法......希望吗?

注意:据我所知,有一个 Visual Studio 选项允许仅调试用户代码,但仅限于托管代码。

编辑:能够通过堆栈跟踪和大量时间跟踪各种事情来解决问题,以了解游戏在哪里挂起。我会选择 Sjoerd 的答案作为正确的答案,但是,如果有人对允许自动执行此类任务的工具/技术有建议,请务必添加您的答案!

I am working on a (relatively complex) game. The game freezes in release mode. The freeze happens after 1-2 min. of game-play. The current configuration of the release mode that I have allows me to break (that is go into debug), which is good, but may give me wrong information but that is fine for this particular case (I can turn off the optimization for a single file/function/code).

Problem is, I (we, since we are a team) don't know where it is hanging. It is not as simple as one relatively small infinite loop that is hanging, as other things (Graphics, sound) are being updated, just that the game-play has stalled. The main game loop (an infinite loop) is always running and is very long/complex, so stepping through is going to be a pain (but it is one of the options).

The first thing I tried is Visual Studio's break all but it always breaks in code that is not mine and consequently shows me assembly output. Eventually, with enough persistence, SVN history checking and commenting out code I will be able to figure out where it is hanging, but there has to be a better way... hopefully?

Note: There is a Visual Studio option I am aware of that allows debugging user code only, but that is managed code only.

EDIT: Was able to solve the problem via stack trace and lots of hours of keeping track of various things to see where the game is hanging. I will select Sjoerd's answer as the correct one, however, if someone has a suggestion for a tool/technique that allows to automate such a task, by all means, add your answer!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

蓝色星空 2024-12-01 02:38:13

如果您中断并遇到不属于您的本机代码,请检查调用堆栈。调用堆栈是为到达代码中的当前点而调用的函数列表。在堆栈中向上移动一些级别,直到遇到当前正在运行的方法。

If you break and you encounter native code that is not yours, check the call stack. The call stack is the list of functions that got called to reach the current point in the code. Go up some levels in the stack until you encounter the method which is currently running.

兔姬 2024-12-01 02:38:13

当程序挂起时,点击 Visual Studio 中的暂停按钮。

这应该会在当前行中断调试器。然后您可以逐步查看发生了什么。

Hit the pause button in Visual Studio while the program is hung.

This should break the debugger at the current line. You can then step through and see what is happening.

难得心□动 2024-12-01 02:38:13

作为调试符号和中断(如果可能的话,这是首选工具)的替代方案,请添加日志记录:游戏(和其他应用程序)拥有一个巨大的日志记录系统并不少见,它们可以使用编译器标志打开和关闭,以便他们仍然可以在“发布版本”中进行某种调试/跟踪。如果您的日志记录工作正常,您应该了解发生了什么和没有发生什么,并至少了解哪里出了问题。

As an alternative to debugging symbols and breaks (which is the tool of choice when possible), add logging: It is not uncommon for games (and other apps) to have a huge logging system they can turn on and off with a compiler flag so they can still do some kind of debugging/tracing in "release builds". If your logging works fine you should see what is and what is not happening and get at least some idea where things go wrong.

打小就很酷 2024-12-01 02:38:13

如果应该执行的代码没有执行,您可能永远无法通过中断捕获问题。发生这种情况的方式有很多种。仅几个:

  • 您有一些参数指示执行下一次更新的时间。如果以某种方式将其设置为某个大数字,则执行更新的代码将很高兴地看到不需要执行任何操作。下一个!这可能会导致程序看起来像是挂起的程序,即使它根本没有真正挂起。状态更新和图形函数仍按规定的速率调用。

  • 您可能会使用一些代表时间的计数器和一些用于增加时间的舍入机制。如果计数器是 32 位有符号整数,并且计数器的粒度为 0.1 微秒,则仅 3.6 分钟后就会达到 INT32_MAX。现在时间被冻结,因此您再次遇到可能无法执行更新的情况。

  • 您正在使用单精度浮点数来表示时间,并通过time += delta_t;更新时间,如果您的delta_t,这将在几分钟后停止工作是10微秒。这是冻结时间的另一种机制。

编辑
您是否查看过各个线程的 CPU 使用情况?上述问题可能会导致物理或游戏线程在几分钟后 CPU 使用率急剧下降。如果玩游戏的线程永久锁定,您也可能会出现此行为,但在这里您可能(使用正确的工具)得到该线程始终处于睡眠状态的指示。

You might well never be able to catch the problem via an interrupt if the code that should be executing isn't executing. There are lots of ways this can happen. Just a few:

  • You have some parameter that indicates the time at which the next update is to be performed. If this somehow gets set to some big number, the code that does the update will happily see that nothing needs to be done. Next! This can give all the appearances of a hung program even though it isn't really hung at all. The state update and the graphics functions are still being called at their prescribed rate.

  • You may some counter that represents time and some rounding mechanism for incrementing time. If the counter is a 32 bit signed int and the granularity of your counter is 0.1 microseconds, you will hit INT32_MAX after just 3.6 minutes. Now time is frozen, so once again you have a situation where updates may not be performed.

  • You are using a single precision floating point number to represent time and update time via time += delta_t; This will stop working after a couple of minutes if your delta_t is 10 microseconds. This is yet another mechanism by which time can be frozen.

Edit
Have you looked at the CPU usage in your various threads? The above problems might cause the physics or game-playing thread to exhibit a drastic drop in CPU usage after a couple of minutes. You might also get this behavior if the game playing thread is perpetually locked, but here you might (with the right tool) get an indication that that thread is always asleep.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文