3

我正在开发一个需要大量内存分配(大量图像缓冲区)的 android 应用程序。为此,我正在使用 Android NDK。我遇到了一个奇怪的崩溃。我希望这不是重复的帖子(在浏览了以前的帖子之后)

应用程序崩溃并出现以下错误:I/DEBUG(187): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000004

  1. 我以前遇到过分段错误并已解决。

  2. 我很确定我正在正确分配和取消分配内存,因为我为 Windows 设置了相同的设置,确认没有内存泄漏并且我没有访问任何未分配的位置。(没有取消引用,没有错误的指针)。在 Windows 上测试时未发现内存损坏。

  3. 我还确定为分配和释放进行的 JNI 调用在代码中的适当位置。只有在使用完成时才会清除内存。

  4. 每次崩溃发生时,Backtrace 都会显示不同的 API 调用,以及发生错误的位置。我已经记录了日志,并且没有一个指针为空,它们与预期的一样。

  5. 此崩溃非常随机地发生。偶尔。 一个。当我长时间在应用程序内时。 。在应用程序内部执行大量操作时。但它大部分时间都运行良好。

谁能建议我的代码中的内存是如何损坏的。可能是什么原因造成的。

4

3 回答 3

6

检查您可能从结构或数组访问字段的位置。我之所以这么说是因为错误的地址是 00000004,它是 NULL 地址之后的 4 个字节。检查每个字段访问,特别是在多次执行的代码中。此外,检查 malloc/new 的 NULL 返回,您的设备可能内存不足。

由于您说当执行大量操作或应用程序长时间运行时会出现此问题,所以我会检查内存泄漏。您的应用程序可能是消耗所有设备内存的应用程序。如果您有自定义分配器/释放器,您可能希望使用全局计数器,对于每次增加它的分配,对于每次释放,减少它。如果计数器太高,则表示内存泄漏。

于 2013-12-23T00:39:42.153 回答
2

当堆栈损坏时,通常会发生随机位置的崩溃,因此您应该仔细查看局部变量。例如,用 M 或类似的东西覆盖长度为 N 的数组。

于 2013-07-04T13:04:56.140 回答
1

fault addr 00000004 => 意味着堆栈已损坏(非常接近 0 addr)。

这是一个示例,您可以如何轻松地复制此错误,因为意外取消引用如下字符串:

int a = foo();
LOGE("Foo() is %d", a ? "ok" : "not ok"); 

它应该是“%s”而不是“%d”

希望它对某人有所帮助。

于 2016-04-25T04:52:39.657 回答