static void check_one_map (Map **inout, gpointer data, gsize len, const char *filename) { Map *map; /* stop if have we already encountered this map. */ for (map = *inout; map; map = map->next) if (map->start == data && map->len == len) return; /* allocate a new Map record */ map = malloc (sizeof(Map)); map->start = data; map->len = len; map->next = *inout; *inout = map; /* output a new Map log entry */ log_uint (LOG_MAGIC_MAP); log_pointer (data); log_uint (len); log_uint (strlen (filename)); log_binary (filename, strlen (filename)); }
static char* log_copy(uint32_t length, char *log) { char *buffer; log_free(log_pool.size); buffer = log_pointer(log_alloc(length)); strncpy(buffer, log, length); return buffer; }
static gpointer debug_malloc (gsize n_bytes) { guint total_levels = stack_depth + stack_levels_to_ignore; gpointer *context = g_newa (gpointer, total_levels); guint n_levels = gsk_backtrace (context, total_levels); AllocationContext *ac; AllocationHeader *header; if (n_bytes == 0) return NULL; if (n_levels <= stack_levels_to_ignore) n_levels = 0; else n_levels -= stack_levels_to_ignore; context += stack_levels_to_ignore; ac = get_allocate_context (n_levels, context); ac->n_bytes_used += n_bytes; ac->n_blocks_used += 1; header = malloc (sizeof (AllocationHeader) + n_bytes + 4); assert (header != NULL); header->size = n_bytes; header->context = ac; memcpy (header->underrun_detection_magic, underrun_detection_magic, 4); memcpy ((char*)(header + 1) + n_bytes, overrun_detection_magic, 4); if (log_fd >= 0) { guint i; check_needs_map_entries (n_levels, context); log_uint (LOG_MAGIC_MALLOC); log_uint (n_bytes); log_uint (n_levels); for (i = 0; i < n_levels; i++) log_pointer (context[i]); log_pointer (header + 1); } return header + 1; }
static gpointer debug_realloc (gpointer mem, gsize n_bytes) { #if 0 AllocationHeader *header = ((AllocationHeader*)mem) - 1; guint old_size; assert (memcmp (header->underrun_detection_magic, underrun_detection_magic, 4) == 0); assert (memcmp ((char*)(header + 1) + header->size, overrun_detection_magic, 4) == 0); assert (header->context->n_bytes_used >= header->size); old_size = header->size; header = realloc (header, sizeof (AllocationHeader) + n_bytes + 4); header->size = n_bytes; memcpy ((char*)(header + 1) + n_bytes, overrun_detection_magic, 4); header->context->n_bytes_used -= old_size; header->context->n_bytes_used += n_bytes; return header + 1; #else void *rv; guint size; if (mem) { AllocationHeader *header = ((AllocationHeader*)mem) - 1; assert (memcmp (header->underrun_detection_magic, underrun_detection_magic, 4) == 0); size = header->size; assert (memcmp ((char*)(header + 1) + size, overrun_detection_magic, 4) == 0); assert (header->context->n_bytes_used >= size); } else size = 0; if (log_fd >= 0) { log_uint (LOG_MAGIC_REALLOC); log_pointer (mem); log_uint (size); } stack_levels_to_ignore++; rv = debug_malloc (n_bytes); memcpy (rv, mem, MIN (n_bytes, size)); debug_free (mem); stack_levels_to_ignore--; return rv; #endif }
static void debug_free (gpointer mem) { AllocationHeader *header = ((AllocationHeader*)mem) - 1; if (mem == NULL) return; assert (memcmp (header->underrun_detection_magic, underrun_detection_magic, 4) == 0); assert (memcmp ((char*)(header + 1) + header->size, overrun_detection_magic, 4) == 0); assert (header->context->n_bytes_used >= header->size); memset (header->underrun_detection_magic, 0, 4); memset ((char*)(header + 1) + header->size, 0, 4); memset (mem, 0xaf, header->size); if (log_fd >= 0) { guint i; guint total_levels = stack_depth + stack_levels_to_ignore; gpointer *context = g_newa (gpointer, total_levels); guint n_levels = gsk_backtrace (context, total_levels); log_uint (LOG_MAGIC_FREE); if (n_levels < stack_levels_to_ignore) n_levels = 0; else n_levels -= stack_levels_to_ignore; context += stack_levels_to_ignore; log_uint (header->size); log_uint (n_levels); for (i = 0; i < n_levels; i++) log_pointer (context[i]); log_pointer (mem); } header->context->n_bytes_used -= header->size; header->context->n_blocks_used -= 1; free (header); }
static void log_uint (guint i) { log_pointer (GUINT_TO_POINTER (i)); }