【问题标题】:Software to track several memory errors in old project?跟踪旧项目中的几个内存错误的软件?
【发布时间】:2010-02-10 02:34:38
【问题描述】:

我从 2 年前开始编写游戏。 有时一些内存错误(即:一个函数返回垃圾而不是它应该返回的内容,或者只在 Linux 上发生的崩溃,而在 GDB 或 Windows 上永远不会发生)似乎是随机发生的。也就是说,我尝试修复它,但几个月后,同样的错误再次困扰着我。

有一个软件(不是 Valgrind,我已经尝试过......它没有找到错误)可以帮助我解决这个问题?或者解决这些错误的方法?我想永久修复它们。

【问题讨论】:

  • 试试其他工具?像 insure++(它是商业的)?
  • 哦,是的,商业工具现在不适合我(特别是因为我根本没有钱……我失业了)
  • 致匿名:更多日志是什么意思?
  • 我在这里做错了什么?我的意思是,为什么我被否决了?

标签: c++ memory allegro


【解决方案1】:

在 Windows 上,您可以在生产环境中自动捕获崩溃异常,并在调试器下将其分析为好像错误发生在您的开发人员 PC 上一样。这是使用“小型转储”文件完成的。您基本上使用 Windows“dbghelp.dll”DLL 来生成线程堆栈、部分或全部堆、寄存器值、加载的模块以及导致崩溃的未处理异常的副本。您可以在 MS Visual Studio 调试器中启动这个“.dmp”文件,就像它是一个可执行文件一样,它会准确地显示崩溃发生的位置。

您可以设置trap for unhandled exceptions 并将迷你转储文件的创建委托给该陷阱中的 dbghelp.dll。您需要保留使用已部署的二进制文件生成的“.pdb”文件,以将内存地址与源代码位置匹配,以获得更好的调试体验。这个话题太深了,无法完全涵盖请参阅此 DLL 上的 Microsoft's documentation

您确实需要能够将 .dmp 文件从崩溃的 PC 复制到您的开发环境中以对其进行全面调试。如果您与用户有不干涉的关系,您将需要选择通过 Internet 使用单独的实用程序应用程序“电话回家”,以将 .dmp 文件传输到您可以访问它的位置。生成 .dmp 文件后,您可以从未处理的异常陷阱中启动应用程序。为了用户隐私,您应该让用户选择是否这样做。

【讨论】:

  • 抱歉,这是一个非崩溃错误,也许幸运(或不幸?)程序继续运行似乎很好,即使周围有错误的值。
  • 哦,是的,我提到了崩溃,但就像我说的,它永远不会在 Windows 上发生。它只发生在 Linux 上,当 GDB 不活动时,并且似乎是随机的(也就是说,当它发生时,我可以多次重现它,但它突然停止发生......:/)
【解决方案2】:

Totalview 调试器(商业软件)可能会捕获崩溃。

Purify(商业软件)可以帮助您发现内存泄漏。

您的代码编译时是否没有编译器警告?你运行 lint 了吗?

【讨论】:

    【解决方案3】:

    您可以尝试的一件事是在您的项目中使用 Hans Boehm GC。它可以用作泄漏检测器,允许您删除看起来可疑的free()delete 语句,并轻松查看它们是否导致内存泄漏。

    【讨论】:

      【解决方案4】:

      AFAIK,Windows 中的 Boundscheck 做得很好。在我的一个项目中,它发现了一些非常奇怪的错误。

      【讨论】:

        【解决方案5】:

        为了在我自己的项目(在 Windows 上)中避免这种情况,我编写了自己的内存分配器,简称为 VirtualAlloc 和 VirtualFree。它为每个请求分配一个额外的页面,将其与最后一页的左侧对齐,并在访问最后一页时使用VirtualProtect 生成异常。这会在现场检测到越界访问,甚至只是读取。

        免责声明:我绝不是第一个有这个想法的人。

        例如,如果页面是 4096 字节,并且调用了 new int[1],分配器将:

        1. 分配8192字节(需要4字节,也就是一页,多出的保护页使总数达到2页)
        2. 将最后一页标记为不可访问
        3. 确定要返回的地址(最后分配的页面从 4096 开始... 4096 - 2 = 4092)

        以下代码:

        main() {
            int *array = new int[10];
            return array[10];
        }
        

        然后会当场产生访问冲突。

        它还有一个(编译时)选项来检测超出分配的 left 侧的访问(即,array[-1]),但这类错误似乎很少见,所以我从未使用过该选项。

        【讨论】:

          猜你喜欢
          • 2010-10-22
          • 2011-04-26
          • 1970-01-01
          • 1970-01-01
          • 2013-02-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多