【问题标题】:Program crashes when run outside IDE在 IDE 外运行时程序崩溃
【发布时间】:2010-10-28 19:30:49
【问题描述】:

我目前正在开发一个在 Windows XP 中处理大量数据的 C++ 程序。我们最大的输入文件导致程序意外终止,没有任何错误消息。有趣的是,当程序从我们的 IDE (Code::Blocks) 运行时,处理文件时没有任何此类问题。

在处理数据时,会将其放入树结构中。在我们完成计算之后,数据被移动到一个 C++ STL 向量中,然后被发送到 OpenGL 中进行渲染。

我希望深入了解可能导致此崩溃的原因。我已经查看了另一个帖子,因为我是新用户,所以我无法发布链接。帖子中的问题与我的非常相似,是由于数组索引越界造成的。但是,我很确定不会发生此类越界错误。

我想知道,在为向量分配空间时,数据集的大小是否会导致问题。我一直在测试程序的系统理论上应该有足够的内存来处理数据(2GB RAM,数据集占用大约 1GB)。当然,如果内存够用,STL 向量在达到其容量时只需将其分配的空间加倍。

谢谢,埃里克

【问题讨论】:

  • 当您在 IDE 之外运行应用程序时,您是重新编译它还是什么?您正在运行调试版本吗?
  • 我已经尝试了调试版本和发布版本,都产生了相同的结果。
  • dll 呢?你是在链接dll还是类似的东西?您是否尝试过通过 cmd 行与 shell 运行它?
  • 发生异常时为什么不能将调试器附加到进程?
  • 从 GTK+ 和 GtkGlExt 库中链接了一些 dll。虽然我没想过从命令行运行...

标签: c++ memory crash


【解决方案1】:

代码在 IDE 中运行(可能在调试器中运行?),但不是独立的,这表明它可能是一个初始化问题。

【讨论】:

  • 感谢您对初始化问题的意思的一些额外解释。
【解决方案2】:

警告级别设置为最高的编译器。

然后检查所有警告。我猜它是一个未初始化的变量(在调试模式下被初始化为 NULL/0)。

就我个人而言,我已经设置了我的模板,以便警告始终处于最大值,并且警告被标记为错误,这样编译就会失败。

【讨论】:

    【解决方案3】:

    您可能会发现配置操作系统以创建故障转储很有帮助(也许,我不知道,仍然使用一些名为“Dr Watson”的 Windows 系统软件),然后您可以将其附加到程序崩溃后的调试器(假设它正在崩溃)。

    您还应该捕获程序可能在没有崩溃转储的情况下半优雅退出的各种方式:atexitset_unexpectedset_terminate 以及可能的其他方式。

    【讨论】:

      【解决方案4】:

      你的记忆模型是什么样的?您是否违反了索引限制(即 sizeof int)?

      【讨论】:

        【解决方案5】:

        事实证明,我们的硬件已达到极限。该程序达到了系统的内存限制并且惨遭失败。在我从命令行将 cerr 挂接到文件之前,我们甚至看不到正在生成的错误语句(感谢 starko)。感谢所有有用的建议!

        【讨论】:

          【解决方案6】:

          听起来你的程序抛出了一个你没有捕捉到的异常。 boost test framework 有一些异常处理程序,可以快速定位异常位置。

          树结构中是否存在可能溢出的索引?您是否在向量中使用超出向量当前大小的索引?

          new vector...    
          vector.push_back()
          vector.push_back()
          vector[0] = xyz
          vector[1] = abc
          vector[2] = slsk // Uh,oh, outside vector
          

          您最大的输入集有多大?你最终分配了 size*size 元素吗?如果是这样,您的最大输入集是否大于 65536 个元素(65536*65536 == MAX_INT)?

          我同意 IDE 在独立时无法正常工作的最可能原因是调试器将内存擦除为 0 或在分配的内存周围使用内存保护。

          如果其他任何事情都失败了,是否可以减少数据集的大小,直到找到确切的工作大小,以及失败的稍微大的示例 - 这可能会提供信息。

          【讨论】:

          • 理论上我可以确定错误发生的确切大小,但正如我在原始帖子的 cmets 中提到的那样,测试用例足够大,因此这是不可行的。事实上,数据集可能大到足以达到整数溢出,我已将其放入待检查的队列中。
          • 如果你确实想找到合适的大小,你会做一个二分搜索——删除一半的数据,把四分之一放回去,删除它的 1/8,等等。这只有在删除时才有效/ 添加数据相对容易。
          • 您在最后一句话中指出了问题所在。输入文件被大量操纵到放入树中的数据中,最终被放入向量中。我真的没有办法从最终数据集中消除任何设定的数量,而无需进行一些严重的黑客攻击,以便在读入数据后很好地丢弃东西。当然,在更简单的情况下这是一个很好的建议。感谢您的持续帮助!
          【解决方案7】:

          我建议您尝试大致确定代码的哪一行导致崩溃。

          由于这只发生在您的 IDE 之外,您可以使用 OutputDebugString 输出当前位置,并使用 DebugView。

          实际上,在 IDE 内部和外部为调试而编译的程序的行为可能完全不同。当从 IDE 加载程序时,它们可以使用一组不同的运行时库。

          最近我被我的代码中的一个计时错误所困扰,不知何故,当从 IDE 调试时,计时总是很好,没有观察到错误,但在发布模式下,错误就在那里。这种 bug 真的是要调试的 PITA。

          【讨论】:

            猜你喜欢
            • 2015-08-10
            • 1970-01-01
            • 2015-10-29
            • 1970-01-01
            • 1970-01-01
            • 2020-09-29
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多