trace: Trace qemu_malloc() and qemu_vmalloc()

It is often useful to instrument memory management functions in order to
find leaks or performance problems.  This patch adds trace events for
the memory allocation primitives.

Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
This commit is contained in:
Stefan Hajnoczi 2010-05-22 18:09:25 +01:00 committed by Anthony Liguori
parent 81a97d9d97
commit cd245a1932
3 changed files with 38 additions and 8 deletions

24
osdep.c
View File

@ -50,6 +50,7 @@
#endif #endif
#include "qemu-common.h" #include "qemu-common.h"
#include "trace.h"
#include "sysemu.h" #include "sysemu.h"
#include "qemu_socket.h" #include "qemu_socket.h"
@ -71,25 +72,34 @@ static void *oom_check(void *ptr)
#if defined(_WIN32) #if defined(_WIN32)
void *qemu_memalign(size_t alignment, size_t size) void *qemu_memalign(size_t alignment, size_t size)
{ {
void *ptr;
if (!size) { if (!size) {
abort(); abort();
} }
return oom_check(VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE)); ptr = oom_check(VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE));
trace_qemu_memalign(alignment, size, ptr);
return ptr;
} }
void *qemu_vmalloc(size_t size) void *qemu_vmalloc(size_t size)
{ {
void *ptr;
/* FIXME: this is not exactly optimal solution since VirtualAlloc /* FIXME: this is not exactly optimal solution since VirtualAlloc
has 64Kb granularity, but at least it guarantees us that the has 64Kb granularity, but at least it guarantees us that the
memory is page aligned. */ memory is page aligned. */
if (!size) { if (!size) {
abort(); abort();
} }
return oom_check(VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE)); ptr = oom_check(VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE));
trace_qemu_vmalloc(size, ptr);
return ptr;
} }
void qemu_vfree(void *ptr) void qemu_vfree(void *ptr)
{ {
trace_qemu_vfree(ptr);
VirtualFree(ptr, 0, MEM_RELEASE); VirtualFree(ptr, 0, MEM_RELEASE);
} }
@ -97,21 +107,22 @@ void qemu_vfree(void *ptr)
void *qemu_memalign(size_t alignment, size_t size) void *qemu_memalign(size_t alignment, size_t size)
{ {
void *ptr;
#if defined(_POSIX_C_SOURCE) && !defined(__sun__) #if defined(_POSIX_C_SOURCE) && !defined(__sun__)
int ret; int ret;
void *ptr;
ret = posix_memalign(&ptr, alignment, size); ret = posix_memalign(&ptr, alignment, size);
if (ret != 0) { if (ret != 0) {
fprintf(stderr, "Failed to allocate %zu B: %s\n", fprintf(stderr, "Failed to allocate %zu B: %s\n",
size, strerror(ret)); size, strerror(ret));
abort(); abort();
} }
return ptr;
#elif defined(CONFIG_BSD) #elif defined(CONFIG_BSD)
return oom_check(valloc(size)); ptr = oom_check(valloc(size));
#else #else
return oom_check(memalign(alignment, size)); ptr = oom_check(memalign(alignment, size));
#endif #endif
trace_qemu_memalign(alignment, size, ptr);
return ptr;
} }
/* alloc shared memory pages */ /* alloc shared memory pages */
@ -122,6 +133,7 @@ void *qemu_vmalloc(size_t size)
void qemu_vfree(void *ptr) void qemu_vfree(void *ptr)
{ {
trace_qemu_vfree(ptr);
free(ptr); free(ptr);
} }

View File

@ -22,6 +22,7 @@
* THE SOFTWARE. * THE SOFTWARE.
*/ */
#include "qemu-common.h" #include "qemu-common.h"
#include "trace.h"
#include <stdlib.h> #include <stdlib.h>
static void *oom_check(void *ptr) static void *oom_check(void *ptr)
@ -34,6 +35,7 @@ static void *oom_check(void *ptr)
void qemu_free(void *ptr) void qemu_free(void *ptr)
{ {
trace_qemu_free(ptr);
free(ptr); free(ptr);
} }
@ -48,18 +50,24 @@ static int allow_zero_malloc(void)
void *qemu_malloc(size_t size) void *qemu_malloc(size_t size)
{ {
void *ptr;
if (!size && !allow_zero_malloc()) { if (!size && !allow_zero_malloc()) {
abort(); abort();
} }
return oom_check(malloc(size ? size : 1)); ptr = oom_check(malloc(size ? size : 1));
trace_qemu_malloc(size, ptr);
return ptr;
} }
void *qemu_realloc(void *ptr, size_t size) void *qemu_realloc(void *ptr, size_t size)
{ {
void *newptr;
if (!size && !allow_zero_malloc()) { if (!size && !allow_zero_malloc()) {
abort(); abort();
} }
return oom_check(realloc(ptr, size ? size : 1)); newptr = oom_check(realloc(ptr, size ? size : 1));
trace_qemu_realloc(ptr, size, newptr);
return newptr;
} }
void *qemu_mallocz(size_t size) void *qemu_mallocz(size_t size)

View File

@ -27,3 +27,13 @@
# system may not have the necessary headers included. # system may not have the necessary headers included.
# #
# The <format-string> should be a sprintf()-compatible format string. # The <format-string> should be a sprintf()-compatible format string.
# qemu-malloc.c
disable qemu_malloc(size_t size, void *ptr) "size %zu ptr %p"
disable qemu_realloc(void *ptr, size_t size, void *newptr) "ptr %p size %zu newptr %p"
disable qemu_free(void *ptr) "ptr %p"
# osdep.c
disable qemu_memalign(size_t alignment, size_t size, void *ptr) "alignment %zu size %zu ptr %p"
disable qemu_valloc(size_t size, void *ptr) "size %zu ptr %p"
disable qemu_vfree(void *ptr) "ptr %p"