FreeLibrary против неявной выгрузки DLL - PullRequest
0 голосов
/ 28 апреля 2010

Я реализовал DLL, включающую функцию ввода DllMain (): -

BOOL APIENTRY DllMain( HMODULE hModule,
  DWORD  ul_reason_for_call,
  LPVOID lpReserved
  )
{
    case DLL_PROCESS_ATTACH:
    /* here im doing file memory mapped through CreateFileMapping() API 
       and using it through MapViewOfFile() API
       storing some data structure in the file mapped area */
    ...
    case DLL_THREAD_ATTACH:
    ...
    case DLL_THREAD_DETACH:
    ...
    case DLL_PROCESS_DETACH:
    /* Here unmapping first through UnmapViewOfFile() API
       then tries to access the stroed data structure which is illegal 
       as we have already closed the file mapping
       This is the buggy code. The order should be first access the mapped memory 
       region and then unmap it */
       cout <<" some message"<<endl;
    ...

}

К сожалению, я допустил ошибку в случае DLL_PROCESS_DETACH и доступа к нелегальной памяти (нарушение прав доступа).

Я создал пример программы, которая загружает библиотеку с помощью функции LoadLibrary (), использует библиотечную функцию и, наконец, вызывает FreeLibrary () и возвращает.

Когда я выполнил эту программу, я не получил никакого сообщения об ошибке. Но если я удаляю FreeLibrary (), в этом случае случай DLL_PROCESS_DETACH выполняется неявно, и на этот раз он выдает диалоговое окно с сообщением об ошибке, указывающим на нарушение прав доступа.

Почему вызов FreeLibrary () подавляет эту ошибку? ИЛИ внутренне это обрабатывает это исключение? Какой предложенный способ.

Обновление: я добавил подробности для ATTACH и DETACH. Вероятно, это поможет, почему мне не ясно о наблюдаемом поведении. При вызове FreeLibrary () я не получил ни одного сообщения об ошибке, но сообщение cout не отображалось. Кажется, он тоже разбился, но не был помечен Но если я удаляю FreeLibrary (), в этом случае случай DLL_PROCESS_DETACH выполняется неявно и дает диалоговое окно нарушения доступа. В идеале в первом случае также должна отображаться ошибка. Поэтому я предполагаю, что FreeLibrary () подавляет эту ошибку нарушения доступа.

Ответы [ 2 ]

2 голосов
/ 05 мая 2010

На странице MSDN для DllMain есть цитата, которая может помочь объяснить, что с вами происходит.

При обработке DLL_PROCESS_DETACH, DLL должна освобождать ресурсы, такие как куча памяти, только если DLL выгружается динамически (параметр lpReserved - NULL). Если процесс завершается (параметр lpvReserved не равен NULL), все потоки в процессе, кроме текущего, либо уже вышли, либо были явно завершены при вызове функции ExitProcess, которая может оставить некоторые ресурсы процесса, такие как кучи в противоречивом состоянии. В этом случае для DLL небезопасно очищать ресурсы. Вместо этого DLL должна позволять операционной системе освобождать память.

Так что, если вы вызываете FreeLibrary, это, по сути, чистое завершение работы. Все еще в действительном состоянии. Любые темы, созданные Dll, все еще существуют. Вся его память все еще вокруг.

Но если вы просто закроете программу (и не вызовете FreeLibrary), то это больше похоже на аварийное отключение (например, сбой). Ваш Dll получает уведомление от операционной системы, а не приложения. Если это является результатом сбоя, то надеяться, что память все еще действует, не очень хорошая идея. И стек все равно пропал.

Так что я думаю, что вы столкнулись с этой проблемой, потому что несвобожденные библиотеки выгружаются по-разному.

0 голосов
/ 28 апреля 2010

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

Итак, когда вы вызывали FreeLibrary, ваша ошибка в случае DLL_PROCESS_DETACH, вероятно, обращалась к памяти, которая использовалась какой-то другой частью вашей программы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...