编写代码时,我经常检查错误是否发生。一个例子是:
char *x = malloc( some_bytes );
if( x == NULL ){
fprintf( stderr, "Malloc failed.\n" );
exit(EXIT_FAILURE);
}
我过去也使用过strerror( errno )
。
我只编写了小型桌面应用程序,如果程序exit()
在发生错误时无关紧要。
然而,现在,我正在为嵌入式系统(Arduino)编写C代码,我不希望系统在出现错误时退出。我希望它能够进入特定的状态/功能,它可以关闭系统,发送错误报告并安全地空闲。
我可以简单地调用一个error_handler()
函数,但是我可以深入堆栈并且内存非常低,使error_handler()
无法运行。
相反,我希望执行有效地崩溃堆栈,释放一堆内存并开始整理掉电和错误报告。如果系统没有安全断电,则存在严重的火灾风险。
是否有一种在低内存嵌入式系统中实现安全错误处理的标准方法?
编辑1:
我将限制在嵌入式系统中使用malloc()
。在这种特殊情况下,如果文件格式不正确,则在读取文件时会发生错误。
答案 0 :(得分:2)
也许你正在等待神圣和神圣的setjmp
/longjmp
,那个前来拯救他们所有需要记忆的罪孽的人?
#include <setjmp.h>
jmp_buf jumpToMeOnAnError;
void someUpperFunctionOnTheStack() {
if(setjmp(jumpToMeOnAnError) != 0) {
// Error handling code goes here
// Return, abort(), while(1) {}, or whatever here...
}
// Do routinary stuff
}
void someLowerFunctionOnTheStack() {
if(theWorldIsOver)
longjmp(jumpToMeOnAnError, -1);
}
修改:出于与您说的相同的原因,不希望在嵌入式系统上执行malloc()
/ free()
。这简直是不可操作的。除非你使用很多的返回代码/ setjmp()
来释放内存中的内存......
答案 1 :(得分:1)
如果您的系统有看门狗,您可以使用:
char *x = malloc( some_bytes );
assert(x != NULL);
assert()
的实现可能类似于:
#define assert (condition) \
if (!(condition)) while(true)
如果看门狗发生故障,系统将进行复位。重启时系统会检查复位原因,如果复位原因是“看门狗复位”,系统会转到安全状态。
<强>更新强>
在进入while
循环之前,assert
冷也输出错误信息,打印堆栈跟踪或将一些数据保存在非易失性存储器中。
答案 2 :(得分:0)
使用setjmp(3)
设置恢复点,并longjmp(3)
跳转到它,将堆栈恢复到setjmp点的状态。它不会释放malloced内存。
通常,如果可以避免,它在嵌入式程序中为not a good idea to use malloc/free。例如,静态数组可能就足够了,甚至使用alloca()
稍微好一些。