Domanda

Supponendo che l'ultima XCode e GCC, che è il modo corretto per eseguire l'override le funzioni di allocazione di memoria (credo operatore new/delete così).Il debug di memoria i contatori sono troppo lenti per un gioco, ho solo bisogno di alcune statistiche di base che posso fare io con il minimo impatto.

So che è facile a Linux grazie ai ganci, e questo è stato banale sotto codewarrior dieci anni fa, quando ho scritto HeapManager.

Purtroppo smartheap non ha più una versione per mac.

Nessuna soluzione corretta

Altri suggerimenti

Vorrei usare precarico libreria per questo compito, perché non richiede la modifica del programma in esecuzione. Se si ha familiarità con il solito modo di Unix per fare questo, è quasi una questione di sostituzione LD_PRELOAD con DYLD_INSERT_LIBRARIES.

Il primo passo è quello di creare una biblioteca con codice come questo, allora costruirlo utilizzando le opzioni di libreria di collegamento condivise regolari (gcc -dynamiclib):

void *malloc(size_t size)
{
    void * (*real_malloc)(size_t);
    real_malloc = dlsym(RTLD_NEXT, "malloc");

    fprintf(stderr, "allocating %lu bytes\n", (unsigned long)size);
    /* Do your stuff here */

    return real_malloc(size);
}

Si noti che se anche si deviare calloc() e la sua attuazione chiamate malloc(), potrebbe essere necessario codice aggiuntivo per verificare come sei stato chiamato. programmi C ++ dovrebbe essere abbastanza sicuro perché l'operatore new chiama malloc() comunque, ma essere consapevoli che nessuna norma impone che. Non ho mai incontrato un'implementazione che non ha utilizzato malloc(), però.

Infine, impostare l'ambiente in esecuzione per il vostro programma e lanciarlo (potrebbe richiedere aggiustamenti a seconda di come la vostra shell gestisce le variabili di ambiente):

export DYLD_INSERT_LIBRARIES=./yourlibrary.dylib
export DYLD_FORCE_FLAT_NAMESPACE=1
yourprogram --yourargs

la dyld pagina di manuale per ulteriori informazioni sulle variabili di ambiente linker dinamico.

Questo metodo è piuttosto generica. Ci sono limitazioni, tuttavia:

      
  • Non sarà in grado di deviare le chiamate di sistema dirette   
  • Se l'applicazione in sé i trucchi utilizzando dlsym() per caricare l'indirizzo di malloc, la chiamata non verranno deviate. A meno che, tuttavia, si trucco indietro di anche deviando dlsym!

La tecnica malloc_default_zone accennato http: // liste. apple.com/archives/darwin-dev/2005/Apr/msg00050.html sembra funzionare ancora, si veda ad esempio http: // codice. google.com/p/fileview/source/browse/trunk/fileview/fv_zone.cpp?spec=svn354&r=354 per un utilizzo esempio, che sembra essere simile a quello che si intende.

Dopo molte ricerche (qui incluso) e le questioni con il 10,7 ho deciso di scrivere un post su questo argomento: Come impostare ganci malloc in OSX Lion

Troverete alcuni buoni link alla fine del post con più informazioni su questo argomento.

La soluzione di base:

malloc_zone_t *dz=malloc_default_zone();
if(dz->version>=8)
{
    vm_protect(mach_task_self(), (uintptr_t)malloc_zones, protect_size, 0, VM_PROT_READ | VM_PROT_WRITE);//remove the write protection
}
original_free=dz->free;
dz->free=&my_free; //this line is throwing a bad ptr exception without calling vm_protect first
if(dz->version==8)
{
    vm_protect(mach_task_self(), (uintptr_t)malloc_zones, protect_size, 0, VM_PROT_READ);//put the write protection back
}

Questa è una vecchia questione, ma mi sono imbattuto in esso durante il tentativo di fare da solo. Mi sono incuriosito su questo argomento per un progetto personale su cui stavo lavorando, soprattutto per assicurarsi che quello che ho pensato è stato deallocato automaticamente veniva correttamente deallocata. Ho finito per scrivere un'implementazione C ++ per permettermi di monitorare la quantità di heap allocata e lo confermano se ho così scelto.

https://gist.github.com/monitorjbl/3dc6d62cf5514892d5ab22a59ff34861

Come osserva nome, questo è OSX-specifica. Tuttavia, ero in grado di fare questo su ambienti Linux che utilizzano il malloc_usable_size

Esempio

#define MALLOC_DEBUG_OUTPUT
#include "malloc_override_osx.hpp"

int main(){
   int* ip = (int*)malloc(sizeof(int));
   double* dp = (double*)malloc(sizeof(double));

   free(ip);
   free(dp);
}

Edificio

$ clang++ -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk \
          -pipe -stdlib=libc++ -std=gnu++11 -g -o test test.cpp
$ ./test
0x7fa28a403230 -> malloc(16) -> 16
0x7fa28a403240 -> malloc(16) -> 32
0x7fa28a403230 -> free(16) -> 16
0x7fa28a403240 -> free(16) -> 0

Spero che questo aiuti qualcun altro in futuro!

Se le statistiche di base di cui avete bisogno possono essere raccolti in un semplice wrapper, un rapido (e un po ' sporca) trucco è proprio l'utilizzo di alcune #define sostituzione di macro.

void* _mymalloc(size_t size)
{
    void* ptr = malloc(size);

    /* do your stat work? */

    return ptr;
}

e

#define malloc(sz_) _mymalloc(sz_)

Nota:se la macro è definita prima il _mymalloc definizione finirà per sostituire la malloc chiamata all'interno di quella funzione di partire con la ricorsione infinita...quindi, assicurarsi che questo non è il caso.Si potrebbe desiderare in modo esplicito #undef prima che la definizione di funzione e semplicemente (ri)definire in seguito, a seconda di dove si finisce tra cui per, si spera di evitare questa situazione.

Credo che se si definisce una malloc () e free () nel file .c incluso nel progetto il linker risolvere tale versione.

Ora poi, come intende implementare malloc?

Scopri Emery Berger - l'autore della memoria del allocatore Hoard - approccio per sostituire l'allocatore su OSX all'indirizzo https://github.com/emeryberger/Heap-Layers/blob/master/wrappers/macwrapper.cpp (e pochi altri file è possibile tracciare da soli seguendo la include).

Questo è complementare alla risposta di Alex, ma ho pensato questo esempio era più to-the-punto di sostituire il sistema previsto allocatore.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top