有没有一个好的指南可以设计和跟踪/控制C语言的错误系统?

4

我对C开发中的软件工程方面还很陌生;是否有一个好的指南,可以教我如何为C项目(特别是嵌入式项目)设计错误跟踪或错误控制系统?如果有关于C库错误跟踪的内容,那就更好了。


你是在谈论处理运行时错误的机制/模式吗?还是缺陷跟踪系统(如FogBugz,Bugzilla等)? - Gabe
首先,一种用于跟踪/报告C代码(特别是嵌入式)运行时错误的方法。 - jparker
3个回答

5
在我的经验中,这里的策略可以分为几个不同的阵营。
  • Use of global variables ala errno. How this works is essentially any function can store an error code in the global variable, so after executing the function you can read the error code to see if it executed properly. There are some obvious issues here when working in a multithreaded environment. Although it appears that POSIX.1c specifies a solution to that problem.

  • Have every function return an error code. For example:

    RESULT_CODE my_function(int param1, int param2);
    
    RESULT_CODE error_code = my_function(10, 2);
    
这种方法的问题在于,您失去了直接从函数返回值的能力。
  • Every function has an extra parameter that stores the result code. For example:

    void my_function(int param1, int param2, RESULT_CODE *err);
    
    RESULT_CODE error_code;
    my_function(10, 2, &error_code);
    switch (error_code)
    {
        case RESULT_OK:
            // all OK
            break;
        case RESULT_NO_MEM:
            // out of memory
            break;
        // etc...
    }
    

我曾在商业实时操作系统中看到过这种方法的成功应用,并且个人更喜欢它,因为我认为它是最不限制性的。唯一可能的缺点是,即使您不关心结果,您也必须显式声明一个变量来存储错误代码。在某种意义上,我实际上有点喜欢这个要求,因为它迫使您不断地考虑如何处理错误。


1

以下是您需要定义的基本内容:

  • 跟踪级别(例如调试、警报、警告、信息、关键等)。您还应该设置当前跟踪级别,因此如果当前跟踪级别为INFO,则会打印所有具有高于info的跟踪级别的消息。如果当前跟踪级别为critical,则仅打印关键消息。

   enum _TraceLevelType
   { 
        INFO = 0,
        DEBUG,
        WARNING,
        ERROR,
        CRITICAL
    } TraceLevelType;
  • 错误代码,我认为最好的方法是创建一个大的枚举。像这样:

   enum _ErrorType
   {
        //Internal errors 0-100
        APPLICATION_FAILURE = 0,
        ...
        MEMORY_FAULT,
        //UI ERRORS  101-200
        INVALID_OPTION_SELECTED = 101,
        ....
        ...
    }ErrorType;

  • 消息队列,你应该有一个机制,让每个人都能发送消息,并且这些消息被正确排队。由于你正在处理嵌入式系统,这非常关键。你不想在实时操作系统上花时间打印调试消息。因此,管理错误代码的线程应该具有非常低的优先级,并且所有接收到的消息都应该被发布到队列中,这样当调度程序决定调用它时,你就可以将printfs打印到控制台或任何你决定的输出中。

因此,你的错误方法将是这样的:


TraceError(TraceLevelType traceLevel, ErrorType errorType, char *msg)
{
    if(CURRENT_TRACE_LEVEL <= traceLevel)
       /* Ignore message */
    else
       /*Queue the Message*/
}         

你也可以添加更多的参数来指示哪个模块发送了错误,但我认为基本上就是这样。



网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接