Frage

Mit Linux / GCC / C ++, würde Ich mag etwas aufnehmen stderr, wenn malloc / free / Neu / Löschen aufgerufen werden. Ich versuche, eine Bibliothek Speicherzuordnungen zu verstehen, und so würde Ich mag diese Ausgabe zu erzeugen, während ich Unit-Tests laufen lasse. Ich benutze valgrind für mem Lecksuche, aber ich kann nicht eine Option finden, um es nur Zuweisungen log zu machen.

Irgendwelche Ideen? Ich suche eine möglichst einfache Lösung. die Bibliothek neu zu kompilieren, ist keine Option.

War es hilfreich?

Lösung

malloc_hook(3) können Sie Ihre eigene malloc Funktion global dazwischenstellen. (Es gibt __realloc_hook __free_hook usw. als gut, ich habe sie einfach weggelassen der Einfachheit halber.)

#include <stdio.h>
#include <malloc.h>

static void *(*old_malloc_hook)(size_t, const void *);

static void *new_malloc_hook(size_t size, const void *caller) {
    void *mem;

    __malloc_hook = old_malloc_hook;
    mem = malloc(size);
    fprintf(stderr, "%p: malloc(%zu) = %p\n", caller, size, mem);
    __malloc_hook = new_malloc_hook;

    return mem;
}

static void init_my_hooks(void) {
    old_malloc_hook = __malloc_hook;
    __malloc_hook = new_malloc_hook;
}

void (*__malloc_initialize_hook)(void) = init_my_hooks;
$ cat >mem.c <<'EOF'
(the code above)
EOF
$ cc -fPIC -shared -o mem.so mem.c
$ LD_PRELOAD=./mem.so ls
0x7ffc14931adc: malloc(5) = 0xb40010
0x7ffc1492c6b0: malloc(120) = 0xb40030
0x7ffc1497f61a: malloc(12) = 0xb40010
0x7ffc1492be38: malloc(776) = 0xb400b0
…

printf nennen könnte malloc, weshalb wir den Haken vorübergehend rückgängig gemacht werden. Achten Sie auf diese Option, wenn, wenn Sie malloc in irgendeiner Weise einhaken.

Andere Tipps

Sie können Anrufe auf malloc Trace / kostenlos mit ltrace:

#include <stdlib.h>

int main (void)
{
  void *ptr = malloc(10);
  free(ptr);

  return 0;
}


$ g++ test.cpp -o test
$ ltrace -e malloc,free ./test
malloc(10)                                       = 0x804a008
free(0x804a008)                                  = <void>
+++ exited (status 0) +++

neu verfolgen / löschen Anrufe ohne Neukompilierung Sie wahrscheinlich so etwas wie LD_PRELOAD verwenden, müssen die Anrufe mit dem eigenen Versionen außer Kraft zu setzen, das ist genau das, was LeakTracer hat, die vielleicht tun, was Sie wollen.

Dieser Artikel (nach unten scrollen nach unten) eine sehr klare und kurze Beschreibung der sieht, wie die globalen new und delete Operatoren in C ++ außer Kraft zu setzen (beachten sie, dass es kein Beispiel für new[] liefert, aber es ist vom Konzept her ähnlich).

Soweit zwingendes malloc und frei, da Sie unter Linux arbeiten und mit GCC, ist die einfachste Methode, malloc_hook und free_hook zu verwenden. Hier ist eine sehr gute Beschreibung, wie diese Funktionen arbeiten.

Ich habe das selbst nicht getestet, aber ich bin ziemlich sicher, dass diese funktionieren würde:

  • Da Sie nicht wollen, die Bibliothek, so dass sinnvolle Ausgabe (gegenüber nur „neu für 23 Byte genannt“) neu kompilieren kann verlangen, einen Stack-Trace zu bekommen. Ich erinnere mich an Funktionen mit dem Stack zu navigieren, aber ich kann sie jetzt nicht finden. Vielleicht ein Aufruf zum System () und pstack (1) kann den Trick tun.

  • Sie können Bediener neu neu definieren und löschen, und setzen diese neue Definition vor der std c ++ Bibliothek. Dies kann nicht fangen die Anrufe von Containern und Standardkomponenten, die die Bibliothek in Frage verwendet. Dies würde eine relink erfordern.

  • Die Anwendung kann LD_PRELOAD verwenden Operator zu ändern, neue und löschen dynamisch. Dies würde nicht eine erneute Verbindung benötigen, wenn Ihre Anwendung dynamisch verbunden ist.

Hoffe, dass dieser Zeiger Hilfe, ich bin traurig, dass ich nicht über ein Rezept.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top