Question

En supposant que le dernier XCode et GCC, ce qui est la bonne façon de passer outre les fonctions d'allocation de mémoire (je suppose que l'opérateur new / supprimer ainsi). Les allocataires de mémoire de débogage sont trop lents pour un jeu, je viens besoin de quelques statistiques de base que je peux me faire avec un impact minimal.

Je sais que facile sous Linux en raison des crochets, ce qui était négligeable sous CodeWarrior il y a dix ans quand je l'ai écrit HeapManager.

Malheureusement SmartHeap n'a plus une version mac.

Pas de solution correcte

Autres conseils

J'utiliser préchargement bibliothèque pour cette tâche, car elle ne nécessite pas de modification du programme en cours. Si vous êtes familier avec la manière Unix habituelle pour ce faire, il est presque une question de remplacement LD_PRELOAD avec DYLD_INSERT_LIBRARIES.

La première étape consiste à créer une bibliothèque avec un code comme celui-ci, puis construire à l'aide de la bibliothèque régulièrement partagées des options de liaison (de 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);
}

Notez que si vous aussi déviez calloc() et sa mise en œuvre des appels malloc(), vous devrez peut-être un code supplémentaire pour vérifier comment vous êtes appelé. C ++ programmes devraient être assez sûr parce que l'opérateur appelle new malloc() de toute façon, mais sachez qu'aucune norme impose que. Je ne l'ai jamais rencontré une mise en œuvre qui n'a pas utilisé malloc(), cependant.

Enfin, mettre en place l'environnement en cours d'exécution pour votre programme et le lancer (pourrait nécessiter des ajustements en fonction de comment votre shell variables d'environnement):

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

Voir la page de manuel dyld plus d'informations sur les variables d'environnement de liens dynamiques.

Cette méthode est assez générique. Il y a des limites, cependant:

      
  • Vous ne pourrez pas renvoyer les appels système directs   
  • Si la demande astuces lui-même vous en utilisant dlsym() pour charger l'adresse de malloc, l'appel ne seront pas détournés. À moins, cependant, vous bidouiller retour en détournant aussi dlsym!

La technique de malloc_default_zone mentionné au http: // lists. apple.com/archives/darwin-dev/2005/Apr/msg00050.html semble encore du travail, voir par exemple http: // code. google.com/p/fileview/source/browse/trunk/fileview/fv_zone.cpp?spec=svn354&r=354 pour un exemple d'utilisation qui semble être semblable à ce que vous avez l'intention.

Après beaucoup de recherches (ici inclus) et des problèmes avec 10,7 J'ai décidé d'écrire un blog sur ce sujet: Comment mettre des crochets malloc OSX Lion

Vous trouverez quelques liens bien à la fin du poste avec plus d'informations sur ce sujet.

La solution de 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
}

Ceci est une vieille question, mais je suis tombé sur tout en essayant de faire moi-même. Je suis curieux de ce sujet pour un projet personnel que je travaillais sur, surtout pour vous assurer que ce que je pensais automatiquement désallouée était correctement désallouée. Je fini par écrire une implémentation C ++ pour me permettre de suivre la quantité de tas alloué et en faire rapport si je le voulais.

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

Comme l'indique le nom, c'est Mac OS X spécifique. Cependant, j'ai pu le faire sur les environnements Linux en utilisant le malloc_usable_size

Exemple

#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);
}

Bâtiment

$ 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

Espérons que cela aide quelqu'un d'autre dans l'avenir!

Si les statistiques de base dont vous avez besoin peut être recueillie dans un emballage simple, un truc rapide (et un peu sale) est juste en utilisant une macro remplacement #define.

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

    /* do your stat work? */

    return ptr;
}

et

#define malloc(sz_) _mymalloc(sz_)

Remarque : si la macro est définie avant la définition de _mymalloc il finira par remplacer l'appel malloc dans cette fonction, vous laissant avec une récursion infinie ... donc en assurer est pas le cas. Vous voudrez peut-être #undef explicitement avant cette définition de la fonction et simplement (re) définir ce en fonction après l'endroit où vous finissez par y compris pour éviter cette situation, espérons.

Je pense que si vous définissez un malloc () et free () dans votre propre fichier .c inclus dans le projet l'éditeur de liens résoudre cette version.

Maintenant, comment comptez-vous mettre en œuvre malloc?

Consultez Emery Berger - l'auteur de la mémoire de Hoard allocateur - approche pour remplacer l'allocateur sur OSX

scroll top