Substituição de malloc definida pelo usuário
Os usuários podem substituir o subsistema de memória (malloc, calloc, realloc, free, mallopt e mallinfo subroutines) com um de seu próprio design.
O subsistema de memória existente funciona para aplicações encadeadas e não encadeadas. O subsistema de memória definido pelo usuário deve ser o threadsafe para que ele funcione em processos encadeados e não encadeados. Como não há verificações para verificar se ele é, se um módulo de memória não threadsafe é carregado em um aplicativo encadeado, a memória e os dados podem estar corrompidos.
O subsistema de memória definido pelo usuário 32-e 64-bit objetos devem ser colocados em um arquivo com o objeto compartilhado de 32-bit denominadomem32.oe o objeto compartilhado de 64-bit denominadomem64.o.
- __malloc__
- __free__
- __realloc__
- __calloc__
- __mallinfo__
- __mallopt__
- __malloc_init__
- __malloc_prefork_lock__
- __malloc_postfork_unlock__
- __malloc_start__
- __posix_memalign__
A execução não para se esses símbolos não existirem.
- void *__malloc__(size_t):
- Esta função é o equivalente ao usuário da subroutine malloc .
- void __free__(void *):
- Esta função é o equivalente ao usuário da subroutine free .
- void *__realloc__(void *, size_t):
- Esta função é o equivalente ao usuário da subroutine realloc .
- void *__calloc__(size_t, size_t):
- Esta função é o equivalente ao usuário da subroutine calloc .
- int __mallopt__(int, int):
- Esta função é o equivalente ao usuário da subroutine mallopt .
- struct mallinfo __mallinfo__():
- Esta função é o equivalente ao usuário da subroutine mallinfo .
void __malloc_start__()- Esta função será chamada uma vez antes de qualquer outro ponto de entrada malloc definido pelo usuário ser chamado.
void __posix_memalign__()- Esta função é o equivalente de usuário da subroutina posix_memalign . Se este símbolo não existir, a execução não irá parar, mas uma chamada feita para a subroutine posix_memalign causará resultados inesperados.
- void __malloc_init__(void)
- Chamado pela rotina de inicialização do pthread. Esta função é usada para inicializar o subsistema de memória do usuário encadeado. Na maioria dos casos, isso inclui criar e inicializar alguma forma de bloqueio de dados. Mesmo se o módulo do subsistema de memória definido pelo usuário estiver ligado a libpthreads.a, o subsistema de memória definido pelo usuário deverá funcionar antes__malloc_init__()é chamado.
- void __malloc_prefork_lock__(void)
- Chamado por pthreads quando oforksubroutine é chamada. Esta função é usada para insumo que o subsistema de memória está em um estado conhecido antes dofork()e fica assim até que ofork()retornou. Na maioria dos casos isso inclui adquirir os bloqueios do subsistema de memória.
- void __malloc_postfork_unlock__(void)
- Chamado por pthreads quando oforksubroutine é chamada. Esta função é usada para tornar o subsistema de memória disponível no pai e no filho após umfork. Isso deve desfazer o trabalho feito por__malloc_prefork_lock__. Na maioria dos casos, isso inclui a liberação de bloqueios do subsistema de memória.
- Módulo mem.exp :
__malloc__ __free__ __realloc__ __calloc__ __mallopt__ __mallinfo__ __malloc_init__ __malloc_prefork_lock__ __malloc_postfork_unlock__ __malloc_start__ - mem_functions32.o módulo:
Contém todas as funções 32-bit necessárias
- mem_functions64.o módulo:
Contém todas as funções 64-bit necessárias
- Criação de 32-bit objeto compartilhado:
ld -b32 -m -o mem32.o mem_functions32.o \ -bE:mem.exp \ -bM:SRE -lpthreads -lc - Criação de 64-bit objeto compartilhado:
ld -b64 -m -o mem64.o mem_functions64.o \ -bE:mem.exp \ -bM:SRE -lpthreads -lc - Criação do arquivo (o nome de objetos compartilhados deve sermem32.opara o objeto 32bit emem64.opara o objeto 64bit ):
ar -X32_64 -r archive_name mem32.o mem64.o
Habilitando o subsistema de memória definido pelo usuário
- A variável de ambiente MALLOCTYPE
- Os comandos_malloc_user_defined_namevariável global no aplicativo do usuário
Para utilizar a variável de ambiente MALLOCTYPE , o arquivo contendo o subsistema de memória definido pelo usuário é especificado configurando-se MALLOCTYPE parauser:archive_nameonde archive_name está no aplicativo'slibpathou o caminho é especificado na variável de ambiente LIBPATH .
char *_malloc_user_defined_name="archive_name"onde archive_name deve estar na libpath do aplicativo ou um caminho especificado na variável de ambiente LIBPATH .
- Quando um aplicativo setuid é executado, a variável de ambiente LIBPATH é ignorada de modo que o arquivo deve estar na libpath do aplicativo.
- archive_name não pode conter informações de caminho.
- Quando ambos a variável de ambiente MALLOCTYPE e a_malloc_user_defined_namevariável global são usadas para especificar o archive_name, o arquivo especificado por MALLOCTYPE substituirá o especificado por_malloc_user_defined_name.
32-bit e 64-bit considerações
Se o arquivo não contiver ambos os objetos compartilhados de 32-bit e 64-bit bits e o subsistema de memória definido pelo usuário foi ativado usando a variável de ambiente MALLOCTYPE , haverá problemas executando processos de 64-bit bits a partir de 32-bit aplicativos e 32-bit processos a partir de 64-bit aplicativos. Quando um novo processo é criado usando a subroutine exec , o processo herda o ambiente do aplicativo de chamada. Isso significa que a variável de ambiente MALLOCTYPE será herdada e o novo processo tentará carregar o subsistema de memória definido pelo usuário. Se o membro de arquivo não existir para este tipo de programa, a carga falhará e o novo processo sairá.
Considerações do encadeamento
Todas as funções fornecidas devem funcionar em um ambiente multiencadeado. Mesmo se o módulo estiver vinculado a libpthreads.a, pelo menos__malloc__()deve trabalhar antes__malloc_init__()é chamado e pthreads é inicializado. Isso é necessário porque a inicialização pthread requermalloc()antes__malloc_init__()é chamado.
Todas as funções de memória fornecidas devem funcionar em ambientes encadeados e não encadeados. Os comandos__malloc__()função deve ser capaz de ser executado até a conclusão sem ter quaisquer dependências em__malloc_init__()(ou seja,__malloc__()deve presumir inicialmente que__malloc_init__()tem não ainda executado.) Depois__malloc_init__()tiver concluído,__malloc__()pode contar com qualquer trabalho feito por__malloc_init__(). Isso é necessário porque a inicialização pthread usamalloc()antes__malloc_init__()é chamado.
- Os comandos__multi_threadedvariável é zero até que um encadeamento é criado quando ele se torna diferente de zero e não será redefinido para zero para esse processo.
- Os comandos__n_pthreadsvariável é-1até que pthreads tenha sido inicializado quando for configurado como1. A partir desse ponto sobre ele é uma contagem do número de threads ativas.
Exemplo:
Se__malloc__()Usapthread_mutex_lock(), o código pode parecer semelhante ao seguinte:
if (__multi_threaded)
pthread_mutex_lock(mutexptr);
/* ..... work ....... */
if (__multi_threaded)
pthread_mutex_unlock(mutexptr);
Neste exemplo,__malloc__()é impedido de executar funções pthread antes de pthreads ser totalmente inicializado. Os aplicativos de rosca única também são acelerados porque o bloqueio não é feito até que um segundo encadeamento seja iniciado.
Limitações
Subsistemas de memória gravados em C++ não são suportados devido à inicialização e às dependências do libC.a e do subsistema de memória libc.a
As mensagens de erro não são traduzidas porque o subroutine setlocale usamalloc()para inicializar os locales. Semalloc()falha então a subroutine setlocale não pode finalizar e o aplicativo ainda está noPOSIXCódigo do idioma. Portanto, apenas as mensagens em inglês padrão serão exibidas.
Os programas construídos estaticamente não podem usar o subsistema de memória definido pelo usuário sem recompilação.
Relatório de erro
A primeira vez que a subroutine malloc é chamada, o objeto 32-ou 64-bit no arquivo especificado pela variável de ambiente MALLOCTYPE é carregado. Se a carga falhar, uma mensagem será exibida e as saídas do aplicativo. Se a carga for bem-sucedida, uma tentativa é feita para verificar se todos os símbolos necessários estão presentes. Se algum símbolo estiver faltando, o aplicativo é finalizado e a lista de símbolos ausentes será exibida.