exponenta event banner

Ненормальное завершение обработчика выхода

Функция обработчика выхода прерывает нормальное выполнение программы

Описание

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

  • Обработчики выхода - это функции, предназначенные для выполнения при завершении программы. Эти функции сначала регистрируются со специфическими функциями, такими как atexit, (WinAPI) _onexit, или at_quick_exit().

  • Некоторые функции, которые могут вызвать аномальные выходы: exit, abort, longjmp, или (WinAPI) _onexit.

Риск

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

Зафиксировать

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

Примеры

развернуть все

#include <stdlib.h>

volatile int some_condition = 1;
void demo_exit1(void)
{
    /* ... Cleanup code ... */
    return;
}
void exitabnormalhandler(void)
{
    if (some_condition)
    {
        /* Clean up */
        exit(0);
    }
    return;
}

int demo_install_exitabnormalhandler(void)
{

    if (atexit(demo_exit1) != 0) /* demo_exit1() performs additional cleanup */
    {
        /* Handle error */
    }
    if (atexit(exitabnormalhandler) != 0)
    {
        /* Handle error */
    }
    /* ... Program code ... */
    return 0;
}

В этом примере: demo_install_exitabnormalhandler регистрирует два обработчика выхода, demo_exit1 и exitabnormalhandler. Обработчики выхода вызываются в обратном порядке, в котором они зарегистрированы. Когда программа заканчивается, exitabnormalhandler прогоны, затем demo_exit1. Однако exitabnormalhandler требования exit прерывание процесса завершения программы. Имея это exit внутри обработчика выхода вызывает неопределенное поведение, так как программа не завершена безопасно.

Исправление - Удалить exit из обработчика выхода

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

#include <stdlib.h>

volatile int some_condition = 1;
void demo_exit1(void)
{
    /* ... Cleanup code ... */
    return;
}
void exitabnormalhandler(void)
{
    if (some_condition)
    {
        /* Clean up */
        /* Return normally */
    }
    return;
}

int demo_install_exitabnormalhandler(void)
{

    if (atexit(demo_exit1) != 0) /* demo_exit1() continues clean up */
    {
        /* Handle error */
    }
    if (atexit(exitabnormalhandler) != 0) 
    {
        /* Handle error */
    }
    /* ... Program code ... */
    return 0;
}

Информация о результатах

Группа: Программирование
Язык: C | C++
По умолчанию: Откл.
Синтаксис командной строки: EXIT_ABNORMAL_HANDLER
Воздействие: среднее
ИДЕНТИФИКАТОР CWE: 705
Представлен в R2016b