捕获未初始化的指针

时间:2015-11-10 12:33:36

标签: c embedded rtos

我试图捕获传递给函数的坏指针。在我以前使用的裸机嵌入式应用程序中:

namespace :assets do
  task :precompile do
    on release_roles(fetch(:assets_roles)) do
      within release_path do
        with rails_env: fetch(:rails_env) do
          execute :rake, "assets:precompile"
        end
      end
    end
  end

  task :backup_manifest do
    on release_roles(fetch(:assets_roles)) do
      within release_path do
        # snipped…
      end
    end
  end

  task :restore_manifest do
    on release_roles(fetch(:assets_roles)) do
      within release_path do
        # snipped…
      end
    end
  end
end

如果指针的特定内存位置初始化为零,则效果很好。

我注意到FreeRTOS和RTX之类的其他内容用0xA5这样的模式填充内存(用于堆栈使用高级水印)。因此,单位化指针将具有一些非零的初始值。

当然,我意识到即使零初始化内存也会变为非零。因此,我希望有人能够更好地检测未初始化的指针。

由于这是一个嵌入式系统,我正在考虑使用函数检查指针是否在正确的内存范围内。在ST32F4xx上,它将是0x20000000到0x20020000,或者是0x10000000到0x10010000以及外围地址范围。

部分化指针的最大原因通常是在固件库中声明未初始化的外围句柄结构。 assert()宏用于帮助尽快检测这些。

欢迎提出建议

1 个答案:

答案 0 :(得分:1)

选项一是做你正在做的事情:检查NULL,检查它是否在正确的地址空间,检查它是否正确对齐(如果你试图引用非32位对齐的内存,ARM将会出错)。然后希望你不会遇到很多问题,你会得到一个有效的无效指针,正如Sourav在评论中指出的那样。

选项二是使用静态分析工具(如Coverity)来检查使用未初始化指针的所有执行路径。根据您获取值的位置,可能无法找到问题。

最后,既然你是裸机,你就可以覆盖错误处理程序。我使用STM32F4已经有一段时间,但我记得你可以覆盖硬错误处理程序,所以它不应该是一个问题。然后设置一个正在测试指针的全局标志,并取消引用它。如果它触发了错误处理程序,请检查标志 - 如果已设置,只需注意它是无效的并且什么都不做。

示例代码:

volatile int faultTest;
volatile int faultHappened;

_Bool validatePointer(void *p)
{
    faultTest = 1;
    faultHappened = 0;
    int n = *(int*)p;
    faultTest = 0;

    return faultHappened;
}

void fault_handler(void)
{
    if (faultTest)
    {
        faultHappened = 1;
        return;
    }
    // regular fault code
}