在出现错误的情况下安全退出特定国家

时间:2015-09-12 09:27:04

标签: c embedded malloc exit safety-critical

编写代码时,我经常检查错误是否发生。一个例子是:

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()。在这种特殊情况下,如果文件格式不正确,则在读取文件时会发生错误。

3 个答案:

答案 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()稍微好一些。