【问题标题】:Cannot Debug I/DEBUG(187): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000004无法调试 I/DEBUG(187):信号 11 (SIGSEGV),代码 1 (SEGV_MAPERR),故障地址 00000004
【发布时间】:2013-07-02 12:03:25
【问题描述】:

我正在开发一个需要大量内存分配(大量图像缓冲区)的 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. 此崩溃非常随机发生。偶尔。 一个。当我长时间在应用程序中时。 b。在应用程序内部执行大量操作时。但它大部分时间都运行良好。

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

【问题讨论】:

    标签: android segmentation-fault


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

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

      【讨论】:

      • 您好,感谢您的回复。我的本机代码有一个全局结构,它有指向不同缓冲区的指针。我有两个 API,一个要分配,一个要解除分配。我一直在我的代码中使用这些。我解除分配(比如当我在 UI 中按下完成时)。你能在这看到什么可疑的东西。??
      • 如果您分配的内存已损坏,通常会在使用此内存的地方发生崩溃。如果您有全局分配和解除分配功能,您可以尝试与 MS 编译器类似的操作。分配更多的内存然后请求并在开始和结束处放置一些标记字节。释放时用已知模式覆盖内存。这可能有助于检查您是否仍在使用该内存。对于损坏的堆栈,您只能尝试通过放置日志文件并找到重复重现崩溃的场景来固定它。
      【解决方案3】:

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

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

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

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

      希望对某人有所帮助。

      【讨论】:

      • 为什么你确定它是堆栈损坏的?更有可能是通过指向类实例的空指针访问类数据成员。
      猜你喜欢
      • 2018-05-29
      • 1970-01-01
      • 2020-07-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-01
      • 1970-01-01
      • 2022-12-20
      相关资源
      最近更新 更多