Сгенерируйте Автономный Код C/C++, Который Обнаруживает и Сообщает об Ошибках времени выполнения

Во время разработки, прежде чем вы сгенерируете код C/C++, это - лучшая практика, чтобы протестировать сгенерированный код путем выполнения версии MEX алгоритма. Однако некоторые ошибки происходят только на целевом компьютере. Чтобы обнаружить эти ошибки, сгенерируйте автономные библиотеки и исполняемые файлы, которые обнаруживают и сообщают об ошибках времени выполнения, такой как за пределы индексация массива.

По умолчанию обнаружение ошибки времени выполнения отключено для автономных библиотек и исполняемых файлов. Включить обнаружение ошибки времени выполнения и сообщающий для автономных библиотек и исполняемых файлов:

  • В командной строке используйте свойство RuntimeChecks настройки кода.

    cfg = coder.config('lib'); % or 'dll' or 'exe'
    cfg.RuntimeChecks = true;
    codegen -config cfg myfunction
  • В MATLAB® Приложение Coder™, в диалоговом окне настроек проекта, на панели Debugging, устанавливает флажок Generate run-time error checks.

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

Сгенерированный код C по сравнению со сгенерированным кодом С++

Если ваш выходной язык является C, сгенерированный код использует fprintf к ошибке при записи обменивается сообщениями к stderr. Затем код использует abort отключать приложение. Если fprintf и abort не доступны, необходимо обеспечить их. abort функция резко отключает программу. Если ваша система поддерживает сигналы, можно отловить сигнал аварийного прекращения работы (SIGABRT) так, чтобы можно было управлять завершением программы.

Если вашим выходным языком является C++, сгенерированный код выдает std::runtime_error исключения для ошибок времени выполнения. Когда вы вызываете сгенерированные функции точки входа C++, можно отловить и обработать эти исключения при помощи try- catch блокируйтесь в своем внешнем Коде С++.

Однако для ошибки времени выполнения проверяет в параллельных областях (также parfor циклы или автоматически параллелизированный for циклы), сгенерированный Код С++ не выдает исключение. В таких ситуациях сгенерированный код использует fprintf к ошибке при записи обменивается сообщениями к stderr, и затем использование abort отключать приложение. Чтобы узнать больше об автоматическом распараллеливании, смотрите, Автоматически Параллелизируют циклы for в Сгенерированном коде.

Пример: сравните сгенерированный C и код С++, которые включают проверки на этапе выполнения

В этом примере вы сравниваете поведение во время выполнения сгенерированного C и Кода С++ для функции MATLAB®, которая вычисляет квадратный корень из ее входного параметра. Сгенерированный код может принять только неотрицательные вещественные значения и производит ошибку времени выполнения для отрицательных входных параметров:

  • Сгенерированный код C использует fprintf записать сообщение об ошибке в stderr. Затем код использует abort отключать приложение.

  • Сгенерированный Код С++ выдает std::runtime_error исключение для этой ошибки времени выполнения. На C++ основная функция, которую вы пишете, чтобы вызвать сгенерированную функцию, вы отлавливаете и обрабатываете это исключение при помощи try- catch блок.

Задайте функцию MATLAB

Задайте функцию MATLAB errorCheckExample в отдельном файле. Эта функция вычисляет квадратный корень из своего входного параметра:

type errorCheckExample
function y = errorCheckExample(x)
y = sqrt(x);
end

Сгенерируйте библиотеку C и исполняемый файл

Сгенерируйте динамически соединенную библиотеку C для errorCheckExample это принимает двойной скалярный вход. Используйте объект настройки кода с RuntimeChecks набор параметров к true. Кроме того, используйте -d опция, чтобы назвать папку генерации кода как codegen_c_dll.

cfg = coder.config('dll');
cfg.RuntimeChecks = true;
codegen -config cfg errorCheckExample -args 1 -d codegan_c_dll -report
Code generation successful: To view the report, open('codegan_c_dll/html/report.mldatx')

Откройте отчет генерации кода и смотрите файл errorCheckExample.c. Функция C, сгенерированная для вашей функции MATLAB, имеет подпись double errorCheckExample(double x). Вычислить квадратный корень, errorCheckExample вызывает sqrt библиотечная функция, которая вычисляет только действительные квадратные корни. Так, errorCheckExample может принять только положительные входные параметры. Для отрицательных входных параметров, errorCheckExample вызывает сгенерированную служебную функцию rtErrorWithMessageID это использует fprintf записать сообщение об ошибке в stderr и затем использование abort отключать приложение.

static void rtErrorWithMessageID(const int b, const char *c,
                                 const char *aFcnName, int aLineNum)
{
  fprintf(stderr,
          "Domain error. To compute complex results from real x, use "
          "\'%.*s(complex(x))\'.",
          b, c);
  fprintf(stderr, "\n");
  fprintf(stderr, "Error in %s (line %d)", aFcnName, aLineNum);
  fprintf(stderr, "\n");
  fflush(stderr);
  abort();
}

При генерации кода библиотеки генератор кода также производит пример основные файлы main.h и main.c в examples подпапка папки сборки. Поддержка C файлы main_runtime_check.h и main_runtime_check.c измененные версии этих файлов в качестве примера. Модифицированный main функция вызывает errorCheckExample(-4), который производит ошибку времени выполнения.

Запустите эти команды, чтобы сгенерировать исполняемый файл C с помощью модифицированных основных файлов. Назовите папку codegen_c_exe генерации кода. Назовите исполняемый файл errorCheckExample_c при помощи -o опция с codegen команда.

cfg = coder.config('exe');
cfg.RuntimeChecks = true;
cfg.CustomSource = 'main_runtime_check.c';
cfg.CustomInclude = pwd;

codegen -config cfg main_runtime_check.c main_runtime_check.h errorCheckExample -args 1 -o errorCheckExample_c -d codegen_c_exe
Code generation successful.

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

if isunix
    system('./errorCheckExample_c');
elseif ispc
    system('errorCheckExample_c.exe');
else
    disp('Platform is not supported');
end
Domain error. To compute complex results from real x, use 'sqrt(complex(x))'.
Error in sqrt (line 13)
./errorCheckExample_c: Aborted

Сгенерируйте библиотеку C++ и исполняемый файл

Сгенерируйте динамически соединенную библиотеку C++ для errorCheckExample это принимает скаляр дважды вход. Используйте объект настройки кода с RuntimeChecks набор параметров к true. Кроме того, используйте -d опция, чтобы назвать папку генерации кода как codegen_cpp_dll.

cfg = coder.config('dll');
cfg.RuntimeChecks = true;
codegen -config cfg -lang:c++ errorCheckExample -args 1 -d codegen_cpp_dll -report
Code generation successful: To view the report, open('codegen_cpp_dll/html/report.mldatx')

Откройте отчет генерации кода и смотрите файл errorCheckExample.cpp. Подобно функции C, сгенерированной в предыдущем разделе, errorCheckExample может принять только положительные входные параметры. Для отрицательных входных параметров, errorCheckExample вызывает служебную функцию rtErrorWithMessageID. Но в этом случае, служебная функция выдает std:runtime_error исключение, которое можно отловить и обработать в рукописном main функция.

static void rtErrorWithMessageID(const char *b, const char *aFcnName,
                                 int aLineNum)
{
  std::stringstream outStream;
  ((outStream << "Domain error. To compute complex results from real x, use \'")
   << b)
      << "(complex(x))\'.";
  outStream << "\n";
  ((((outStream << "Error in ") << aFcnName) << " (line ") << aLineNum) << ")";
  throw std::runtime_error(outStream.str());
}

При генерации кода библиотеки генератор кода также производит пример основные файлы main.h и main.c в examples подпапка папки сборки. Поддержка файлы C++ main_runtime_check.hpp и main_runtime_check.cpp измененные версии этих файлов в качестве примера. Модифицированный main() функция вызывает errorCheckExample(-4) в try-catch блок. Блок отлавливает исключение и распечатывает модифицированное сообщение путем предварительного ожидания строки "Caught excaption: " к сообщению, что перехваченная исключительная ситуация содержит.

Запустите эти команды, чтобы сгенерировать исполняемый файл C++ использование модифицированных основных файлов. Назовите папку codegen_cpp_exe генерации кода. Назовите исполняемый файл errorCheckExample_cpp.

cfg = coder.config('exe');
cfg.RuntimeChecks = true;
cfg.CustomSource = 'main_runtime_check.cpp';
cfg.CustomInclude = pwd;

codegen -config cfg -lang:c++ main_runtime_check.cpp main_runtime_check.hpp errorCheckExample -args 1 -o errorCheckExample_cpp -d codegen_cpp_exe
Code generation successful.

Запустите сгенерированный исполняемый файл. Заметьте, что это распечатывает модифицированное сообщение об ошибке.

if isunix
    system('./errorCheckExample_cpp');
elseif ispc
    system('errorCheckExample_cpp.exe');
else
    disp('Platform is not supported');
end
Caught exception: Domain error. To compute complex results from real x, use 'sqrt(complex(x))'.
Error in sqrt (line 13)

Ограничения

Обнаружение ошибки времени выполнения и сообщающий в автономном коде имеет эти ограничения:

  • Сообщения об ошибке находятся на английском языке только.

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

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

  • Если сгенерированный код C завершает работу, выявление ошибок и создание отчетов, что программное обеспечение не высвобождает средства, такие как выделенная память. Сгенерированный Код С++ не имеет этого ограничения. Если сгенерированный Код С++ завершает работу, выделенная память и другие ресурсы выпущены.

  • В автономном коде, функции error отображает сообщение, которое указывает, что ошибка произошла. Видеть фактическое сообщение, заданное error, необходимо сгенерировать и запустить MEX-функцию.

  • В автономном коде, если названо больше чем одним аргументом, функцией assert не сообщает ошибка и не отключает выполнение. Если названо отдельным аргументом, например, assert(cond), если cond не постоянный true значение, сообщает об ошибке и отключает выполнение.

Смотрите также

| |

Похожие темы