Во время разработки, прежде чем вы сгенерируете код 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 errorCheckExamplefunction 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