Во время разработки, прежде чем вы сгенерируете код 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, сгенерированный код использует fprintf
для записи сообщений об ошибке в stderr
. Затем код использует abort
чтобы завершить работу приложения. Если fprintf
и abort
не доступны, вы должны предоставить их. The abort
функция внезапно завершает работу программы. Если ваша система поддерживает сигналы, можно поймать сигнал прерывания (SIGABRT
), чтобы вы могли контролировать завершение программы.
Если ваш целевой язык C++, сгенерированный код выдает std::runtime_error
исключения для ошибок времени выполнения. При вызове сгенерированных функций точки входа C++ можно поймать и обработать эти исключения при помощи try
- catch
блокируйте внешний код С++.
Однако для проверки ошибок во время выполнения внутри параллельных областей (или parfor
циклы или автоматически параллелизованные for
циклы), сгенерированный код С++ не выдает исключение. В таких ситуациях сгенерированный код использует fprintf
для записи сообщений об ошибке в stderr
, а затем использует abort
чтобы завершить работу приложения. Дополнительные сведения об автоматической параллелизации см. в разделе Автоматическая параллелизация для циклов в Сгенерированном коде.
Обнаружение ошибок времени выполнения и создание отчетов в автономном коде имеет следующие ограничения:
Сообщения об ошибке доступны только на английском языке.
Некоторые проверки ошибок требуют поддержки двойной точности. Поэтому оборудование, на котором запускается сгенерированный код, должно поддерживать операции двойной точности.
Если программа завершается, программное обеспечение выявления ошибок и создания отчетов не отображает стек во время выполнения. Чтобы просмотреть стек, приложите отладчик.
Если сгенерированный код C заканчивается, программное обеспечение выявления ошибок и создания отчетов не освобождает ресурсы, такие как выделенная память. Сгенерированный код С++ не имеет этого ограничения. Если сгенерированный код С++ завершается, выделенная память и другие ресурсы освобождаются.
В автономном коде функция error
отображает сообщение, указывающее, что произошла ошибка. Чтобы увидеть фактическое сообщение, заданное как error
необходимо сгенерировать и запустить MEX-функцию.
В автономном коде, если вызывается с более чем 1 аргументом, функция assert
не сообщает об ошибке и не прекращает выполнение. Если вызывается с одним аргументом, например, assert(cond)
, если cond
не является постоянным true
значение, сообщает об ошибке и прекращает выполнение.
В этом примере вы сравниваете поведение во время выполнения сгенерированного кода 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)
codegen
| coder.CodeConfig
| coder.EmbeddedCodeConfig