MonoDevelop 调试器崩溃,没有错误消息,使用 Dijkstra 的算法和 2D 数组

Posted

技术标签:

【中文标题】MonoDevelop 调试器崩溃,没有错误消息,使用 Dijkstra 的算法和 2D 数组【英文标题】:MonoDevelop Debugger Crashing with no error message, using Dijkstra's algorithm and 2D array 【发布时间】:2012-11-26 15:38:53 【问题描述】:

我正在使用 C# 和 MonoDevelop 在 Monotouch 中制作 ios 游戏。我有一个非常奇怪的崩溃。

背景信息:制作 2D 战争游戏。我已经实现了 Dijkstra 算法 来计算从源到目的地的最短路径,中间有物体(例如:从这里到那里,但绕过汽车/树木/建筑物/或任何挡路的东西自动地)。我的崩溃似乎与我为这个 Dijkstra 算法的实现创建的二维字节数组有关。如果您从未听说过 Dijkstra 的算法,请查看此图片http://en.wikipedia.org/wiki/File:Dijkstras_progress_animation.gif

基本上,我的2D 数组 中的节点越多,士兵在战场上的移动细节就越多。如果我在二维数组中使用 2,400 个节点,则一切正常/加载正常。但是,如果我将节点数增加到 4,266 以获得更详细的坐标,则程序在计算节点距离时会崩溃。它在崩溃之前完成了大约 30%。

有关崩溃的更多详细信息: 只有在我使用 Debug/iPhone 模式或 Release/iPhone 模式时才会崩溃。当我使用调试/iPhone 模拟器时,它工作正常。还有一点需要注意的是,当我构建应用程序并使用 Debug/iPhone 模式将其传输到我的手机时,然后停止调试器,打开 XCode Instruments,它工作正常!我不知道为什么它可以在模拟器和 XCode Instruments 中工作,但不能在 Monodevelop Debug/iPhone 模式下工作。 XCode Instruments 是否正在做一些“修补”问题的事情?还是 MonoDevelop 的调试器正在做一些事情来“破坏”程序?

让我解释一下您在屏幕截图中看到的内容。我的应用程序被称为“战争游戏”。查看时间线,CPU 使用率约为 100%,从大约 2 秒到大约 35 秒。当 CPU 使用率下降到零时,它就完成了加载。因此,加载 2D 节点数组并用距离填充它们实际上花了大约 33 秒。

请记住,在这种情况下,崩溃有 4,266 个节点,这意味着 2D 数组是一个字节 [4266, 4266] 数组。所以这是二维数组中的 18,198,756 个字节。并且在 XCode Instruments 运行时加载成功,在 MonoDevelop 的 Debug/iPhone Simulator 中运行时加载成功。但在我的 iPhone 4s 上以 Debug/iPhone 模式运行时,它会崩溃且没有错误消息。从屏幕截图中可以看出,此应用的内存使用量约为 60.73MB。

在没有崩溃的实例中,有 2,400 个节点,这意味着 2D 数组是一个字节 [2400, 2400] 数组。所以这是 2D 数组中的 5,760,000 字节。那个在任何地方都工作得很好。

问题显然是,当我将节点数增加到大约 4,266 或更多时,程序崩溃了。但我没有收到错误消息,它只是在加载时突然停止... 这可能是垃圾收集问题吗?您认为我会收到错误消息吗? 这可能是“内存不足”问题吗?但是当它使用 XCode 的 Instruments 加载时,它说我只使用了 60MB,而我之前在这个应用程序中使用了多达 150MB 作为测试,所以我知道在它因“内存不足错误”而崩溃之前,我至少可以使用 150MB 的内存。

这是 XCode Instruments 的内存分配照片

这是 XCode Instruments 的内存泄漏页面的照片

【问题讨论】:

您使用的是递归还是迭代方法?我遇到了 MonoDeveloper 调试器在遇到堆栈溢出时崩溃的问题。 只有在我使用 Debug/iPhone 模式或 Release/iPhone 模式时才会崩溃。 是否有发布版本,由 MonoDevelop 安装手动启动该设备工作?还是不? 由 MonoDevelop 安装但在设备上手动启动的发布版本不起作用。但是,如果我执行 MonoDevelop 安装的构建版本,然后使用 XCode Instruments 启动应用程序,然后关闭应用程序。然后关闭 XCode Instruments 并在设备上手动启动应用程序,它确实可以工作.... 很奇怪吧?几乎就像 XCode Instruments 修复或绕过了一个问题...... 递归或迭代:我不是 100%,但我只是查找了递归与迭代函数的示例,似乎我正在使用迭代。我没有任何函数在循环中调用自己......但很可能我遇到了堆栈溢出问题。无论如何,即使屏幕上没有实际错误,我也可以在构建过程或“崩溃”期间看到我的堆栈吗? 关于递归或迭代方法,我的循环中的任何函数调用是否会被视为“递归”?我有来自数学库的函数调用,例如 Math.Round 和 Math.Sqrt 和 Math.DivRem。对数学库的函数调用是否可能导致堆栈溢出,因为它们实际上被调用了数千次? 【参考方案1】:

这很奇怪。它看起来像一个调试器错误,可能是使用调试器时内存不足的情况(因为这将需要比 正常 构建更多的内存)。

但是,您应该能够手动启动 发布 构建而不会出现问题...就像使用 Xcode 的 Instruments 一样。

我怀疑存在不止一个问题。例如。启动应用程序需要很长时间,并且看门狗会杀死它(用于发布构建)。这在从 Xcode 的 Instrument 启动时仍然有效,因为它会使看门狗静音

如果没有更多信息(不适合 ***),我无法更精确。我建议您打开bug report 并附上调试版本(由 MonoDevelop 启动)和发布版本(手动启动)的崩溃日志。

【讨论】:

感谢您的帮助,您成功了。看门狗在完成加载之前杀死了应用程序。我做了一个测试来证实这一点。堆栈溢出也导致崩溃。我有一些用于转换的简单函数调用和一些导致堆栈溢出的数学库函数调用。我删除了函数调用并将所有代码直接放入循环中。它极大地提高了性能,并允许我增加二维数组中的节点数。

以上是关于MonoDevelop 调试器崩溃,没有错误消息,使用 Dijkstra 的算法和 2D 数组的主要内容,如果未能解决你的问题,请参考以下文章

调试器无法连接到 Monodevelop(模拟器和真实设备)

Unity进阶技巧 - 使用MonoDevelop来断点调试

是否可以看到 WPF 崩溃的错误消息? [复制]

如何阻止MonoDevelop在调试时打开Safari窗口?

iOS 应用程序在使用 XCode 调试器启动时崩溃,在没有调试器的情况下运行良好

sigabrt 没有错误信息