Será que uma fuga de memória no descarregamento de uma DLL causa um vazamento no processo de acolhimento?

StackOverflow https://stackoverflow.com/questions/132242

Pergunta

Considere este caso:

dll = LoadDLL()
dll->do()

...
void do() {
    char *a = malloc(1024);
}
...

UnloadDLL(dll);

Neste ponto, será o 1k alocados na chamada para malloc () estar disponível para o processo de host de novo? A DLL está vinculado estaticamente a CRT.

Foi útil?

Solução

Não, você não escapam.

Se você misturar dll modelos (estático e dinâmico), então você pode acabar com um erro de memória se você alocar memória em uma dll, que você libertar em um diferente (ou libertado no exe)

Isto significa que a pilha criado pela CRT estaticamente ligado não é a mesma pilha como CRT de uma dll diferente.

Se você tivesse ligado com a versão dinâmica do CRT, então você tem um vazamento como a pilha é compartilhado entre todos os CRTs dinamicamente ligadas. Isso significa que você deve sempre projetar seus aplicativos para usar os CRTs dinâmicas, ou garantir que você nunca gerenciar a memória em um limite de dll (ou seja, se você alocar memória em uma dll, sempre fornecem uma rotina para libertá-lo da mesma dll)

Outras dicas

  1. Memória usada por um processo como monitorado pelo sistema operacional é aplicável a todo o processo e não é específico para um DLL.

  2. A memória é dado ao programa em pedaços pela OS, chamados montes

  3. Os gerentes heap (malloc / new etc) ainda dividir os pedaços e as mãos para fora para solicitar o código.

  4. Somente quando uma nova pilha é alocado é o sistema operacional detectar um aumento na memória.

  5. Quando uma DLL é ligado estaticamente para a biblioteca tempo de execução C (CRT), uma cópia privada do CRT com as funções CRT que chama de código da DLL é compilado e colocado em binário do DLL. Malloc também é inclued neste.

  6. Esta cópia privada de malloc será invocado sempre que o código presente dentro da DLL estaticamente ligado tenta alocar memória.

  7. Por isso, um montão privado visível apenas para esta cópia do malloc, é adquirida a partir do OS por este malloc e aloca a memória solicitada pelo código dentro deste montão privado.

  8. Quando os descarrega DLL, ele descarrega seu acervo particular e esse vazamento passa despercebida como toda a pilha é devolvido de volta para o OS .

  9. No entanto, se a DLL é dinamicamente ligado, a memória é alocada por uma versão compartilhada do malloc, global a todo o código que está ligada no modo compartilhado.

  10. A memória alocada por este malloc global, sai de uma pilha que é também a pilha usada para todos os outros códigos que está ligada no modo aka compartilhada dinâmica e, portanto, é comum. Todas as fugas provenientes este montão, portanto, torna-se um vazamento que afeta todo o processo.

Edit -. Descrições do cenário ligando Adicionado

Você não pode dizer. Isso depende da implementação de sua estática e CRT dinâmica. Pode até depender do tamanho da atribuição, pois há CRTs que a frente grandes alocações para o sistema operacional, mas implementar sua própria pilha para pequenas alocações.

O problema com a CRT que vazamentos é claro que ele vazamentos. O problema com a CRT, que não vazamento faz é que o poder executável razoável esperar para usar a memória, como memória malloc'ed deve permanecer utilizável até livre é chamado.

De MSDN potenciais erros Passando CRT objetos através limites DLL

Cada cópia da biblioteca CRT tem um estado separado e distinto. Assim sendo, CRT objetos como identificadores de arquivo, variáveis ??de ambiente e locais são válido apenas para a cópia da CRT onde esses objetos são alocados ou conjunto. Quando uma DLL e seu uso usuários diferentes cópias da biblioteca CRT, você não pode passar essas CRT objetos através do limite DLL e esperam -los para ser apanhada corretamente no outro lado.

Além disso, porque cada cópia do CRT biblioteca tem seu próprio gerenciador de heap, alocação de memória em um biblioteca CRT e passando o ponteiro através de uma DLL limite a ser libertado por um diferente cópia da biblioteca CRT é um potencial causa para a corrupção de pilha.

Espero que isso ajude.

Na verdade, a resposta marcada está incorreto. Esse direito existe uma fuga. Embora seja tecnicamente viável para cada DLL para implementar o seu próprio montão, e libertá-lo no desligamento, a maioria dos montes "tempo de execução" - estático ou dinâmico - são wrappers para o Win32 pilha do processo API

.

A menos que se tenha tomado cuidados específicos para garantir que este não é o caso, a dll vai vazar a alocação por carga, fazer, ciclo de descarga.

Pode-se fazer um teste e ver se há vazamentos de memória. Você executar um teste simples de 30 vezes alocar 1 MB de cada vez. Você deve descobrir isso muito rapidamente.

Uma coisa é certa. Se você memória alocada na DLL você também deve liberar essa memória lá (na DLL).

Por exemplo, você deve ter algo como isto (simples, mas pseudocódigo intuitivo):

dll = DllLoad();

ptr = dll->alloc();

dll->free(ptr);

DllUnload(dll);

Isto deve ser feito porque a DLL tem uma pilha diferente do que o processo original (que carrega a DLL).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top