Remplacement de l’allocateur de mémoire dans MSVC ++

Bien que le moteur d’exécution standard de Microsoft fournisse la version de débogage des fonctions d’allocation, cela ne fonctionne pas vraiment, car vous n’êtes pas censé utiliser le nouveau code nu en C ++, l’instrumentation pointe donc vers la bibliothèque standard ou nulle part, car la bibliothèque standard ne peut pas être instrumentée.

Maintenant, j’ai un code qui peut produire (et enregistrer) des traces d’arrière-plan d’allocation et j’ai également utilisé DUMA . Cependant, les tentatives de remplacement des fonctions d’allocation ont streambuf lorsque nous avons utilisé des stream, car streambuf appelle une variante de débogage et le fait de manière incohérente entre new et delete.

Quelqu’un a-t-il donc l’expérience du remplacement de allocator, en remplaçant les fonctions et non en de sortingstes astuces du préprocesseur, dans le runtime standard de Microsoft? Je suppose que cela implique d’ éviter l’allocateur de débogage, mais je souhaite conserver la définition de _DEBUG pour des raisons évidentes (il en faut beaucoup plus pour le code de débogage).

Remarque: nous sums actuellement bloqués avec Visual C ++ 9.0 (Visual Studio 2008).

Edit: Il est peu probable que l’on évite l’allocateur de débogage, car la bibliothèque standard C ++ doit avoir des définitions cohérentes de new et delete entre les fonctions et les instanciations compilées dans la bibliothèque et les instanciations générées dans le code utilisateur, car l’atsortingbution peut être effectuée par un seul utilisateur. et libération par l’autre. Cela signifie en passant que la définition de variantes en ligne statiques dans l’en-tête à force incluse est peu probable.

Edit2: Ce n’est pas possible avec la liaison dynamic, car Windows lie les symboles de DLL spécifiques. Il est donc impossible de les remplacer au moment de la liaison. Mais nous n’avons pas besoin de liaison dynamic et ne l’utilisons pas car la cible principale est WinCE et la liaison statique y est définie par défaut.

Voici comment nous procédons (avec jemalloc, mais tout autre allocateur est possible):

  1. Comstackz l’allocateur de mémoire personnalisé séparément en tant que bibliothèque C statique.
  2. Liez votre application C ++ à la bibliothèque d’allocateur personnalisée.
  3. Remplacez les opérateurs new et delete dans votre application C ++ pour appeler l’allocateur personnalisé.

Remarques:

  • L’allocateur personnalisé doit être écrit en C, pas en C ++.
  • Il n’est pas possible d’assurer une initialisation suffisamment précoce de l’allocateur à moins qu’il ne réside dans une bibliothèque séparée.
  • Remplacer malloc et free est également possible, mais beaucoup plus difficile sous MSVC, car ceux-ci ne sont pas “faiblement” liés et qu’il existe de nombreuses variantes personnalisées dans MSVC (par exemple, en utilisant le drapeau /FORCE:MULTIPLE lieur).

Exemple de code:

 void* operator new(size_t size) { void* ptr = my_malloc(size); if (ptr) return ptr; else throw std::bad_alloc(); } void* operator new[](size_t size) { void* ptr = my_malloc(size); if (ptr) return ptr; else throw std::bad_alloc(); } void* operator new(size_t size, const std::nothrow_t&) throw() { return my_malloc(size); } void* operator new[](size_t size, const std::nothrow_t&) throw() { return my_malloc(size); } void operator delete(void* pointer) throw() { my_free(pointer); } void operator delete[](void* pointer) throw() { my_free(pointer); } void operator delete(void* pointer, const std::nothrow_t&) throw() { my_free(pointer); } void operator delete[](void* pointer, const std::nothrow_t&) throw() { my_free(pointer); }