【发布时间】:2015-11-10 12:33:35
【问题描述】:
我试图捕获传递给函数的错误指针。在我曾经使用的裸机嵌入式应用程序上:
assert(somePointer != NULL);
如果指针的特定内存位置初始化为零,则此方法效果很好。
我注意到 FreeRTOS 和 RTX 等其他操作系统会使用 0xA5 等模式填充内存(以进行堆栈使用高级水印)。因此,未初始化的指针将具有一些非零初始值。
当然,我意识到即使是零初始化的内存也会变成非零。因此,我希望有人有更好的方法来检测未初始化的指针。
由于这是一个嵌入式系统,我正在考虑让一个函数检查指针是否在正确的内存范围内。在 ST32F4xx 上,这将是 0x20000000 到 0x20020000,或 0x10000000 到 0x10010000 以及外设地址范围。
未初始化指针的最大原因通常是在固件库中声明为未初始化的外围句柄结构。用于帮助尽快检测到这些的 assert() 宏。
欢迎提出建议
【问题讨论】:
-
好吧,标准要求全局变量是
0/null 指针。对于局部变量,您应该使用对(大多数)未初始化的用法发出警告的编译器。其他任何东西充其量都是特定于实现的。检查花费时间和代码。通常手动验证每个指针访问是不可能的,除非您可以容忍大量惩罚(这提出了为什么不使用更便宜的 MCU 的问题)。而assert仅在设置了NDEBUG时才有效。无论哪种方式,您的问题都太宽泛了。 -
只是为了论证,一个未初始化的指针仍然可以指向一个没有分配给你的进程的有意义的内存地址。那怎么样?
-
我仍然很惊讶有人发现这是一个主要问题。在所有可能发生的错误中,取消引用 null 或其他被内存管理硬件捕获的地址甚至都不是什么大问题(除非是间歇性的)。
-
@Sourav 是的,这是正确的。这是问题的原因之一。我希望有人在 C 语言中有一个出色的策略来检测错误指针并愿意分享。
-
@Martin 我希望本地代码以 C++ try/catch 类型的方式处理错误,而不是崩溃到 MemFault 陷阱。我还可以指出,默认情况下,STM32F4xx 系列的陷阱似乎被禁用,因此只会导致一般的“硬故障”。我确实启用了所有特定的陷阱,并使用 MPU 来检测无效的访问范围。请注意,0x0 是 STM32F4xx 中的有效指针,可以在不触发内存故障的情况下取消引用。