Для получения триального ключа
заполните форму ниже
Team License (базовая версия)
Enterprise License (расширенная версия)
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

** На сайте установлена reCAPTCHA и применяются
Политика конфиденциальности и Условия использования Google.
Запросите информацию о ценах
Новая лицензия
Продление лицензии
--Выберите валюту--
USD
EUR
GBP
RUB
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

** На сайте установлена reCAPTCHA и применяются
Политика конфиденциальности и Условия использования Google.
Для получения лицензии для вашего открытого
проекта заполните, пожалуйста, эту форму
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

** На сайте установлена reCAPTCHA и применяются
Политика конфиденциальности и Условия использования Google.
Для получения лицензии для вашего открытого
проекта заполните, пожалуйста, эту форму
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

** На сайте установлена reCAPTCHA и применяются
Политика конфиденциальности и Условия использования Google.
Мне интересно попробовать плагин на:
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

** На сайте установлена reCAPTCHA и применяются
Политика конфиденциальности и Условия использования Google.
Ваше сообщение отправлено.

Мы ответим вам на


Если вы так и не получили ответ, пожалуйста, проверьте папку
Spam/Junk и нажмите на письме кнопку "Не спам".
Так Вы не пропустите ответы от нашей команды.

>
>
OpenMP и исключения (exceptions)

OpenMP и исключения (exceptions)

16 Мар 2009

Мы продолжаем развивать наш статический анализатор VivaMP, и на этот раз хочется рассказать о диагностике ошибок, связанных с использованием исключений (exception) языка Си++ в параллельных регионах (parallel regions).

Поддержка VivaMP была прекращена в 2014 году. По всем возникшим вопросам вы можете обратиться в нашу поддержку.

Под параллельным регионом имеются виду фрагмент программы, который делится на параллельно выполняемые нити. Параллельно выполняемые нити формируют такими директивами OpenMP как for и sections.Использовать исключения внутри параллельных регионов можно. Но исключения не должны покидать эти параллельные регионы. Исключения должны быть пойманы и обработаны внутри параллельного региона с использованием конструкций try/catch. Если исключение выйдет за приделы параллельного региона, то это приведет к сбою и скорее всего к аварийному завершению программы. Рассмотрим пример некорректного кода:

#pragma omp parallel for num_threads(4)
for(int i = 0; i < 4; i++)
{
  //...
  throw 1;
}

Данный код некорректен, так как исключения будут покидать параллельный регион. Чтобы этого избежать, необходимо использовать другие механизмы передачи информации о возникновении ошибки. Например, код может быть переписан следующим образом:

size_t errCount = 0;
#pragma omp parallel for num_threads(4) reduction(+: errCount)
for(int i = 0; i < 4; i++)
{
  try {
    //...
    throw 1;
  }
  catch (...)
  {
    ++errCount;
  }
}
if (errCount != 0)
  throw 1;

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

Дополнительная сложность состоит в том, что исключение может вызвать не только ваш код, в котором вы напишите throw. Исключения могут быть сгенерированы и в используемых вами функциях или операторах выделения памяти. Рассмотрим следующий, на первый взгляд безобидный пример:

#pragma omp parallel for num_threads(4)
for(int i = 0; i < 4; i++)
{
  float *ptr = new float[10000];
  delete [] ptr;
}

Такой код может годами надежно работать, а может привести к аварийному завершению программы, если в какой-то момент оператор 'new' не сможет выделить объем необходимой памяти. Согласно стандарту языка Си++ оператор new выбрасывает исключение std::bad_alloc если не может выделить необходимый объем памяти. Такой подход позволяет не проверять, выделена ли необходимая память, как это делается в случае использования функции malloc, а сразу начать работу с ней. Если же память не выделена, то программа обработает эту ситуацию в нужном месте. В случае с параллельным регионом необходима дополнительная работа, чтобы корректно обработать ошибку выделения памяти внутри самого региона. Исправленный пример:

#pragma omp parallel for num_threads(4) reduction(+: errCount)
for(int i = 0; i < 4; i++)
{
  try {
    float *ptr = new float[10000];
    delete [] ptr;
  }
  catch (std::bad_alloc &)
  {
    //process error
  }
}

Я думаю, что вы уже догадались, что использование функций внутри параллельных секций дело тоже опасное и неблагодарное. Необходимо или быть уверенным, что функции не генерируют исключений, или обертывать их в try/catch. Неприятный момент в том, что если на момент написания параллельного кода, используемые в нем функции не генерировали исключение, то со временем это может измениться и нужно быть очень аккуратным.

Подводя итог, можно сказать, что исключения являются моментом, о котором нужно постоянно помнить, разрабатывая программу с использованием OpenMP. Чтобы упростить жизнь программистов, мы добавили в анализатор VivaMP три новых диагностических сообщения, которые помогут отловить ошибки связанные с использованием исключений:

V1301. The 'throw' keyword cannot be used outside of a try..catch block in a parallel section

V1302. The 'new' operator cannot be used outside of a try..catch block in a parallel section.

V1303. The FOO function which throws an exception cannot be used in a parallel section outside of a try..catch block.

Диагностическое сообщение V1301 укажет на ошибку в первом примере, а V1302 диагностирует ошибки вызова оператора 'new' вне обработчика исключений. С V1303 все немного сложнее. Сейчас анализатор VivaMP будет предупреждать только о вызове функций, явно помеченных как бросающих исключения, то есть:

void MyThrowFoo() throw(...) { }

Функции не отмеченные "throw(...)" тоже могут бросать исключения, но они не диагностируются как опасные. Этот шаг сделан сознательно, чтобы уменьшить количество лишних диагностических сообщений. Ведь получится, что любой вызов функции в параллельной секции, неэкранированный конструкцией try/catch будет опасным. Хотя именно так оно и есть, но польза от такого количества диагностических сообщений сомнительна. Но возможно именно так себя в дальнейшем будет вести себя анализатор VivaMP в режиме "pedantic mode". И тогда безопасными, буду считать функции, явно помеченные, как не выбрасывающие исключений:

void MyNotThrowFoo() throw() { }

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

#pragma omp parallel num_threads (4)
{
    try {
        if (omp_get_thread_num ()  ==  0) {
            throw CException();
        }
        #pragma omp barrier
    }
    catch(CException &) {
    }
}

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

Дополнительная литература

Популярные статьи по теме
Главный вопрос программирования, рефакторинга и всего такого

Дата: 14 Апр 2016

Автор: Андрей Карпов

Вы угадали, ответ - "42". Здесь приводится 42 рекомендации по программированию, которые помогут избежать множества ошибок, сэкономить время и нервы. Автором рекомендаций выступает Андрей Карпов - тех…
Статический анализ как часть процесса разработки Unreal Engine

Дата: 27 Июн 2017

Автор: Андрей Карпов

Проект Unreal Engine развивается - добавляется новый код и изменятся уже написанный. Неизбежное следствие развития проекта - появление в коде новых ошибок, которые желательно выявлять как можно раньш…
Любите статический анализ кода!

Дата: 16 Окт 2017

Автор: Андрей Карпов

Я в шоке от возможностей статического анализа кода, хотя сам участвую в разработке инструмента PVS-Studio. На днях я был искренне удивлён тому, что анализатор оказался умнее и внимательнее меня.
Эффект последней строки

Дата: 31 Май 2014

Автор: Андрей Карпов

Я изучил множество ошибок, возникающих в результате копирования кода. И утверждаю, что чаще всего ошибки допускают в последнем фрагменте однотипного кода. Ранее я не встречал в книгах описания этого …
Как PVS-Studio оказался внимательнее, чем три с половиной программиста

Дата: 22 Окт 2018

Автор: Андрей Карпов

PVS-Studio, как и другие статические анализаторы кода, часто выдаёт ложные срабатывания. Но не стоит спешить считать странные срабатывания ложными. Это короткая история о том, как PVS-Studio вновь ок…
Бесплатный PVS-Studio для тех, кто развивает открытые проекты

Дата: 22 Дек 2018

Автор: Андрей Карпов

В канун празднования нового 2019 года команда PVS-Studio решила сделать приятный подарок всем контрибьюторам open-source проектов, хостящихся на GitHub, GitLab или Bitbucket. Им предоставляется возмо…
PVS-Studio для Java

Дата: 17 Янв 2019

Автор: Андрей Карпов

В седьмой версии статического анализатора PVS-Studio мы добавили поддержку языка Java. Пришло время немного рассказать, как мы начинали делать поддержку языка Java, что у нас получилось и какие дальн…
Характеристики анализатора PVS-Studio на примере EFL Core Libraries, 10-15% ложных срабатываний

Дата: 31 Июл 2017

Автор: Андрей Карпов

После большой статьи про проверку операционной системы Tizen мне было задано много вопросов о проценте ложных срабатываний и о плотности ошибок (сколько ошибок PVS-Studio выявляет на 1000 строк кода)…
PVS-Studio ROI

Дата: 30 Янв 2019

Автор: Андрей Карпов

Время от времени нам задают вопрос, какую пользу в денежном эквиваленте получит компания от использования анализатора PVS-Studio. Мы решили оформить ответ в виде статьи и привести таблицы, которые по…
Технологии, используемые в анализаторе кода PVS-Studio для поиска ошибок и потенциальных уязвимостей

Дата: 21 Ноя 2018

Автор: Андрей Карпов

Краткое описание технологий, используемых в инструменте PVS-Studio, которые позволяют эффективно обнаруживать большое количество паттернов ошибок и потенциальных уязвимостей. Статья описывает реализа…

Комментарии (0)

Следующие комментарии

На сайте установлена reCAPTCHA и применяются
Политика конфиденциальности и Условия использования Google.
Этот сайт использует куки и другие технологии, чтобы предоставить вам более персонализированный опыт. Продолжая просмотр страниц нашего веб-сайта, вы принимаете условия использования этих файлов. Если вы не хотите, чтобы ваши данные обрабатывались, пожалуйста, покиньте данный сайт. Подробнее →
Принять