# V1045. The DllMain function throws an exception. Consider wrapping the throw operator in a try..catch block.

Анализатор обнаружил код, выбрасывающий и не перехватывающий исключение в теле функции DllMain.

При загрузке динамической библиотеки в процесс эта функция принимает значение DLL_PROCESS_ATTACH в качестве аргумента 'fwdReason'. Если DllMain завершается с ошибкой, она обязана вернуть значение FALSE. В этом случае загрузчик вызывает эту функцию снова со значением DLL_PROCESS_DETACH в 'fwdReason', что приводит к выгрузке DLL. Если функция DllMain завершается в результате исключения, выгрузка библиотеки не происходит.

Пример:

    BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
    {
      ....
      throw 42;
      ....
    }

Ошибку следует обработать в блоке try...catch и корректно вернуть FALSE.

Корректный пример:

    BOOL __stdcall DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
    {
      try
      {
        ....
        throw 42;
        ....
      }
      catch(...)
      {
        return FALSE;
      }
    }

Также исключения могут возникать при вызове оператора 'new'. При невозможности выделения памяти будет сгенерировано исключение 'bad_alloc'. Пример:

    BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
    {
      ....
      int *localPointer = new int[MAX_SIZE];
      ....
    }

Появление исключения возможно при использовании dynamic_cast<Type> при работе со ссылками. При невозможности приведения типов будет сгенерировано исключение 'bad_cast'. Пример:

    BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
    {
      ....
      UserType &type = dynamic_cast<UserType&>(baseType);
      ....
    }

Для исправления данных ошибок следует переписать код таким образом, чтобы 'new' или 'dynamic_cast' были помещены в блок try...catch.

Анализатор также обнаруживает в DllMain вызовы функций, которые потенциально могут выбросить исключение. Пример:

    BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
    {
      ....
      potentiallyThrows();
      ....
    }

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

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

Данная диагностика классифицируется как:

CWE-248 CWE-703 CERT-DCL57-CPP