opengl 如何正确调试并查找崩溃原因?

ovfsdjhp  于 2022-11-04  发布在  其他
关注(0)|答案(7)|浏览(409)

我不知道该怎么办了......没希望了。我已经厌倦了猜测是什么导致了崩溃。最近我注意到一些opengl调用崩溃程序随机在一些gfx卡。所以我真的很偏执什么可以导致崩溃了。这个崩溃的坏事情是,它崩溃后,才使用了很长一段时间的程序,所以我只能猜测是什么问题。
我不记得我对程序做了什么改变,可能会导致崩溃,它已经这么长时间了。但幸运的是,以前的版本没有崩溃,所以我可以复制粘贴一些代码,浪费10个小时,看看在什么时候它开始崩溃...我不认为我想这样做。
程序崩溃后,我使它处理相同的文件约5次连续,每次它使用约200兆字节的内存在该过程中。它崩溃的随机时间,而和之后的阅读过程。
我创建了一个“安全的”free()函数,它检查指针是否为空,然后释放内存,然后将指针设置为空。这难道不是应该这样做的吗?
我观察了任务管理器的内存使用情况,就在它崩溃之前,它开始消耗比平时多2倍的内存。最初的几次加载看起来并没有慢多少,但后来它开始迅速增加一倍的加载速度。这应该告诉我什么关于崩溃?
另外,我是否必须使用clear()手动释放c++向量?或者它们是在使用后自动释放的,例如,如果我在函数中分配向量,它是否会在每次函数结束时被释放?我没有在向量中存储指针。

简单地说:我想学习尽可能快地捕捉该死的bug,我该怎么做呢?使用Visual Studio 2008。

myzjeezk

myzjeezk1#

在一个复杂的操作之后发生的“随机”崩溃几乎可以肯定是堆崩溃的结果。堆崩溃bug是一个 * 婊子 *,因为它们通常在离真正导致bug的地方很远的地方表现出来。我的建议是,既然你在Windows上,就使用Application Verifier,它可以从MS免费下载。
启动AV,配置它来监视你的程序,打开所有内存相关的选项。然后在调试器下运行你的程序。(这两件事会让你的程序运行得 * 极其 * 缓慢。)AV所做的额外检查可能会导致你的程序在一个不同于你目前所看到的地方崩溃,但它将是真实的导致bug的位置。

wfypjpf4

wfypjpf42#

最有可能的情况是内存损坏。您需要一个内存调试器来跟踪此问题;您可以找到建议here
我已经创建了一个“安全”的free()函数,它检查指针是否为NULL,然后释放内存,然后将指针设置为NULL。
检查NULL是不必要的,因为一个符合标准的free(VS 2008就是)会为你做这个检查。仍然有可能释放一个垃圾指针,这会导致问题。
至于将指针设置为NULL,这可能有帮助,但不是万能的。首先,您可能没有将正确的指针设置为NULL。例如,如果您这样做:

void myfree(void *ptr)
{
    free(ptr);
    ptr = NULL;
}

您所做的只是将myfree的本地参数设置为NULL。调用者的指针副本仍然保持不变。

s4n0splo

s4n0splo3#

就像前面说的,这很可能是某个地方的内存泄漏。
Visual Studio has built-in tools for this
基本上,您可以拍摄内存的两个快照,并在某个时间比较它们

yhqotfr8

yhqotfr84#

第一个问题,为什么要在C++中使用free()?通常你应该使用new/delete来管理内存,或者使用new和智能指针来管理内存。
您不必手动清除()的向量。请记住,如果将指向对象的指针存储在向量中,(这不一定是好的做法,有更好的容器),你将不得不在向量被销毁之前分别销毁它们。正如你所说,你没有在向量中存储指针,当向量超出作用域时,它将被销毁--即包含对象被销毁或程序离开了函数的作用域。
随机崩溃通常是内存错误,我建议你装备一个好的内存调试器。在Windows上,这通常意味着Rational Purify或Boundschecker。当然,它有助于找出是什么首先触发了崩溃--没有处理内存不足的情况?空指针引用?宇宙射线?
鉴于对您问题中的评论的回应,我将做以下事情:

  • 更改VS 2008异常拦截,使其在发生访问冲突时中断
  • 在调试器下以调试模式运行程序-不要尝试调试发行版可执行文件
  • 尝试重现您所看到的行为。这会比在释放模式下花费更长的时间,但您最终应该会达到目的。您可能还会得到一些误报。
  • 如果您很清楚哪个(空)指针被取消引用,请assert()该指针,然后在调试器中再次运行程序。
tv6aics1

tv6aics15#

“我不记得我对程序做了什么修改,可能会导致崩溃,这是这么长的时间。但幸运的是,以前的版本没有崩溃,所以我可以复制粘贴一些代码,浪费10个小时,看看它在什么时候开始崩溃。”
这就是为什么Test-Driven Development(TDD)如此震撼的原因。请阅读它,看看它如何帮助您避免这些场景。

wyyhbhjk

wyyhbhjk6#

请注意Noah Roberts和JS Bangs的观点--如果您不熟悉调试器,那么听起来是时候让您熟悉一下了。
我还建议使用类似valgrind的工具-请参阅SO question
另外,我是否必须使用clear()手动释放c++向量?
不,不,不

unhi4e5o

unhi4e5o7#

你真的需要学习使用调试器。按下顶部的播放按钮,或者如果必要的话使用远程调试器功能。如果你不能通过这种方式找到它,那么drwtsn32也是一个选择。

相关问题