Pergunta

Isso é um pouco hipotético e grosseiramente simplificado, mas ...

Suponha um programa que chamará funções escritas por terceiros.Estas partes podem ser consideradas não hostis, mas não podem ser consideradas “competentes”.Cada função receberá alguns argumentos, terá efeitos colaterais e retornará um valor.Eles não têm estado enquanto não estão em execução.

O objetivo é garantir que eles não possam causar vazamentos de memória registrando todos os mallocs (e similares) e liberando tudo após o término da função.

Isso é possível?Isso é prático?

p.s.A parte importante para mim é garantir que nenhuma alocação persista, portanto, maneiras de remover vazamentos de memória sem fazer isso não são úteis para mim.

Foi útil?

Solução

Você não especifica o sistema operacional ou ambiente, esta resposta assume Linux, glibc e C.

Você pode definir __malloc_hook, __free_hook e __realloc_hook para apontar para funções que serão chamadas de malloc(), realloc() e free() respectivamente.Há uma página de manual __malloc_hook mostrando os protótipos.Você pode adicionar alocações de trilha nesses ganchos e depois retornar para deixar o glibc lidar com a alocação/desalocação de memória.

Parece que você deseja liberar quaisquer alocações ativas quando a função de terceiros retornar.Existem maneiras de fazer com que o gcc insira chamadas automaticamente em cada entrada e saída de função usando -finstrument-functions, mas acho que isso seria deselegante para o que você está tentando fazer.Você pode fazer com que seu próprio código chame uma função em sua biblioteca de rastreamento de memória depois de chamar uma dessas funções de terceiros?Você poderia então verificar se há alguma alocação que a função de terceiros ainda não liberou.

Outras dicas

Primeiro, você deve fornecer os pontos de entrada para malloc() e free() e amigos.Como esse código já está compilado (certo?), você não pode depender dele #define para redirecionar.

Então você pode implementá-los da maneira óbvia e registrar que eles vieram de um determinado módulo, vinculando essas rotinas a esses módulos.

A maneira mais rápida envolve nenhum registro. Se a quantidade de memória que eles usam é limitada, por que não pré-alocar todo o "heap" que eles precisarão e escrever um alocador a partir disso?Então, quando terminar, libere toda a "pilha" e pronto!Você poderia estender essa ideia para vários heaps se for mais complexo que isso.

Se você realmente precisa "registrar" e não criar seu próprio alocador, aqui estão algumas idéias.Primeiro, use uma tabela hash com ponteiros e encadeamento interno.Outra seria alocar espaço extra na frente de cada bloco e colocar sua própria estrutura contendo, digamos, um índice em sua "tabela de log" e, em seguida, manter uma lista livre de entradas da tabela de log (como uma pilha, obtendo assim uma lista gratuita). ou colocar um livre de volta é O(1)).Isso ocupa mais memória, mas deve ser rápido.

É prático?Acho que sim, desde que a velocidade seja aceitável.

Você pode executar as funções de terceiros em um processo separado e fechar o processo quando terminar de usar a biblioteca.

Uma solução melhor do que tentar registrar mallocs pode ser colocar as funções em sandbox quando você as chama - dar-lhes acesso a um segmento fixo de memória e, em seguida, liberar esse segmento quando a função terminar de ser executada.

O uso de memória não confinado e incompetente pode ser tão prejudicial quanto o código malicioso.

Você não pode simplesmente forçá-los a alocar toda a memória na pilha?Desta forma seria garantido que seria liberado após o término da função.

No passado, escrevi uma biblioteca de software em C que tinha um subsistema de gerenciamento de memória que continha a capacidade de registrar alocações e liberações e de combinar manualmente cada alocação e liberação.Isso foi útil ao tentar encontrar vazamentos de memória, mas era difícil e demorado de usar.O número de logs era impressionante e demorava muito para entendê-los.

Dito isto, se a sua biblioteca de terceiros tiver alocações extensas, é mais provável que seja impraticável rastrear isso por meio de registro.Se você estiver executando em um ambiente Windows, sugiro usar uma ferramenta como Purify[1] ou BoundsChecker[2] que deve ser capaz de detectar vazamentos em suas bibliotecas de terceiros.O investimento na ferramenta deve se pagar em tempo economizado.

[1]: http://www-01.ibm.com/software/awdtools/purify/ Purificar

[2]: http://www.compuware.com/products/devpartner/visualc.htm Verificador de limites

Como você está preocupado com vazamentos de memória e falando sobre malloc/free, presumo que você esteja em C.Também presumo, com base na sua pergunta, que você não tem acesso ao código-fonte da biblioteca de terceiros.

A única coisa que consigo pensar é examinar o consumo de memória do seu aplicativo antes e depois da chamada, registrar mensagens de erro se forem diferentes e convencer o fornecedor terceirizado a corrigir quaisquer vazamentos encontrados.

Se você tiver dinheiro sobrando, considere usar o Purify para rastrear problemas.Faz maravilhas e não requer código-fonte ou recompilação.Existem também outras bibliotecas malloc de depuração disponíveis que são mais baratas.Cerca Elétrica é um nome que me lembro.Dito isto, os ganchos de depuração mencionados por Denton Gentry também parecem interessantes.

Se você é muito pobre para o Purify, experimente o Valgrind.É muito melhor do que há 6 anos e muito mais fácil de mergulhar do que no Purify.

O Microsoft Windows fornece (use SUA se precisar de um POSIX), muito possivelmente, a infraestrutura heap + (outra API conhecida por usar o heap) mais avançada de qualquer sistema operacional comercial atualmente.

os ganchos de depuração __malloc() e as interfaces de depuração CRT associadas são bons para casos em que você tem o código-fonte para os testes, no entanto, muitas vezes eles podem perder alocações por bibliotecas padrão ou outro código vinculado.Isso é esperado, pois eles são a infraestrutura de depuração de heap do Visual Studio.

sinalizadores é um conjunto muito abrangente e detalhado de recursos de depuração que foi incluído no Windows por muitos anos.Ter funcionalidade avançada apenas para casos de uso de origem e binário (já que é a infraestrutura de depuração de heap do sistema operacional).

Ele pode registrar rastreamentos completos de pilha (repaginando informações simbólicas em uma operação pós-processo), de todos os usuários do heap, para todos os pontos de entrada que modificam o heap, em série, se necessário.Além disso, pode modificar o heap com casos patológicos que podem alinhar a alocação de dados de modo que a proteção de página oferecida pelo sistema VM seja atribuída de maneira ideal (ou seja,aloque o bloco de heap solicitado no final de uma página, para que até mesmo um estouro de byte único seja detectado no momento do estouro.

umdh é uma ferramenta que pode ajudar a avaliar o status em vários pontos de verificação, porém os dados são continuamente acumulados durante a execução do alvo ou não é uma simples parada de depuração de ponto de verificação no contexto tradicional.Também, AVISO, Pela última vez que verifiquei, pelo menos, o tamanho total do buffer circular que armazena as informações da pilha, para cada solicitação é um pouco pequeno (entradas de 64k (entradas + pilha)), então você pode precisar despejar rapidamente para usuários pesados ​​de heap.Existem outras maneiras de acessar esses dados, mas o umdh é bastante simples.

OBSERVAÇÃO existem 2 modos;

  1. MODO 1, umdh {-p:Process-id|-pn:ProcessName} [-f:Nome do arquivo] [-g]
  2. MODO 2, umdh [-d] {Arquivo1} [Arquivo2] [-f:Nome do arquivo]

    Eu não sei que insanidade tomou conta do desenvolvedor que escolheu alternar entre -p:foo especificador de argumento e ordem nua de argumento, mas pode ficar um pouco confuso.

O SDK de depuração funciona com várias outras ferramentas, instantâneo de memória é uma ferramenta que aparentemente se concentra em vazamento de memória e tal, mas eu não a usei, sua milhagem pode variar.

Execute gflags sem argumentos para o modo UI, +arg's e /args são diferente "modos" de uso também.

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