У кого-нибудь есть хорошее руководство по проектированию и отслеживанию ошибок / системе контроля C? - PullRequest
4 голосов
/ 21 июля 2009

Я новичок в разработке программного обеспечения на C; У кого-нибудь есть хорошее руководство о том, как спроектировать систему отслеживания ошибок или контроля ошибок для проекта C (особенно встроенного)? Также полезно кое-что рассказать об отслеживании ошибок для библиотек C.

Ответы [ 3 ]

5 голосов
/ 22 июля 2009

По моему опыту, стратегии здесь делятся на несколько лагерей.

  • Использование глобальных переменных ala errno . Как это работает, по сути, любая функция может сохранить код ошибки в глобальной переменной, поэтому после выполнения функции вы можете прочитать код ошибки, чтобы увидеть, правильно ли он выполнен. Здесь есть некоторые очевидные проблемы при работе в многопоточной среде. Хотя выглядит , POSIX.1c определяет решение этой проблемы.

  • Пусть каждая функция возвращает код ошибки. Например:

    RESULT_CODE my_function(int param1, int param2);
    
    RESULT_CODE error_code = my_function(10, 2);
    

Проблема этого подхода заключается в том, что вы теряете способность возвращать значения непосредственно из функции.

  • Каждая функция имеет дополнительный параметр, в котором хранится код результата. Например:

    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...
    }
    

Я видел, как этот подход успешно используется в коммерческой RTOS, и лично я предпочитаю его, так как считаю его наименее ограничительным. Единственным потенциальным недостатком является то, что вы должны явно объявить переменную для хранения кода ошибки, даже если вам не важен результат. В каком-то смысле мне действительно нравится это требование, поскольку оно заставляет вас постоянно думать о том, как будут обрабатываться ошибки.

1 голос
/ 22 июля 2009

Вот основные вещи, которые вам нужно определить:

  • Уровни трассировки (например, Отладка, Оповещения, Предупреждения, Информация, Критические и т. Д.). У вас также должен быть установлен текущий уровень трассировки, поэтому, если текущий уровень трассировки - INFO, то будут напечатаны все сообщения с уровнем трассировки выше информации. Если текущий уровень трассировки является критическим, то будут напечатаны только критические сообщения.

   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*/
}         

Вы могли бы также иметь больше параметров, чтобы указать, какой модуль отправляет ошибку, но я думаю, что это в основном так.

1 голос
...