fix realloc

This commit is contained in:
Stefani Seibold 2016-05-19 18:12:09 +02:00
parent 3f7f77d105
commit e50dccecb3
3 changed files with 29 additions and 36 deletions

View File

@ -601,7 +601,7 @@ static struct rb_block *process_rb_search_range(struct rb_root *root, unsigned l
while (node) { while (node) {
struct rb_block *this = container_of(node, struct rb_block, node); struct rb_block *this = container_of(node, struct rb_block, node);
if (addr <= this->addr && addr + size > this->addr) if ((addr <= this->addr) && (addr + size > this->addr))
return this; return this;
if (addr < this->addr) if (addr < this->addr)
@ -619,7 +619,7 @@ static struct rb_block *process_rb_search(struct rb_root *root, unsigned long ad
while (node) { while (node) {
struct rb_block *this = container_of(node, struct rb_block, node); struct rb_block *this = container_of(node, struct rb_block, node);
if (addr >= this->addr && addr < this->addr + (this->size ? this->size : 1)) if (addr == this->addr)
return this; return this;
if (addr < this->addr) if (addr < this->addr)
@ -630,23 +630,6 @@ static struct rb_block *process_rb_search(struct rb_root *root, unsigned long ad
return NULL; return NULL;
} }
static struct rb_block *process_rb_block(struct rb_root *root, unsigned long addr)
{
struct rb_node *node = root->rb_node;
while (node) {
struct rb_block *this = container_of(node, struct rb_block, node);
if (addr < this->addr)
node = node->rb_left;
else if (addr > this->addr)
node = node->rb_right;
else
return this;
}
return NULL;
}
static void process_release_mem(struct process *process, struct rb_block *block, unsigned int size) static void process_release_mem(struct process *process, struct rb_block *block, unsigned int size)
{ {
if (block->flags & BLOCK_LEAKED) { if (block->flags & BLOCK_LEAKED) {
@ -694,7 +677,7 @@ static int process_rb_insert_block(struct process *process, unsigned long addr,
parent = *new; parent = *new;
if (addr <= this->addr && addr + n > this->addr) { if ((addr <= this->addr) && (addr + n > this->addr)) {
process_dump_collision(process, this, addr, size, operation); process_dump_collision(process, this, addr, size, operation);
if (options.kill) if (options.kill)
@ -826,7 +809,8 @@ static void process_init(struct process *process, unsigned int swap_endian, unsi
static void realloc_del(struct realloc_entry *re) static void realloc_del(struct realloc_entry *re)
{ {
stack_put(re->stack); if (re->stack)
stack_put(re->stack);
list_del(&re->list); list_del(&re->list);
free(re); free(re);
} }
@ -1197,7 +1181,7 @@ void *process_scan(struct process *process, void *leaks, uint32_t payload_len)
void *new_leaks = leaks; void *new_leaks = leaks;
for(i = 0; i < n; ++i) { for(i = 0; i < n; ++i) {
struct rb_block *block = process_rb_block(&process->block_table, process->get_ulong(leaks)); struct rb_block *block = process_rb_search(&process->block_table, process->get_ulong(leaks));
if (block && !(block->flags & BLOCK_LEAKED)) { if (block && !(block->flags & BLOCK_LEAKED)) {
block->flags |= BLOCK_LEAKED; block->flags |= BLOCK_LEAKED;
@ -1221,7 +1205,7 @@ void *process_scan(struct process *process, void *leaks, uint32_t payload_len)
dump_printf(" leaked bytes: %llu\n", process->leaked_bytes); dump_printf(" leaked bytes: %llu\n", process->leaked_bytes);
for(i = 0; i < new; ++i) { for(i = 0; i < new; ++i) {
struct rb_block *block = process_rb_block(&process->block_table, process->get_ulong(new_leaks)); struct rb_block *block = process_rb_search(&process->block_table, process->get_ulong(new_leaks));
if (dump_printf(" leaked at 0x%08lx (%lu bytes)\n", (unsigned long)block->addr, (unsigned long)block->size) == -1) if (dump_printf(" leaked at 0x%08lx (%lu bytes)\n", (unsigned long)block->addr, (unsigned long)block->size) == -1)
break; break;
@ -1398,6 +1382,9 @@ void process_free(struct process *process, struct mt_msg *mt_msg, void *payload)
debug(DEBUG_FUNCTION, "ptr=%#lx", ptr); debug(DEBUG_FUNCTION, "ptr=%#lx", ptr);
if (!ptr)
return;
block = process_rb_search(&process->block_table, ptr); block = process_rb_search(&process->block_table, ptr);
if (block) { if (block) {
if (block->addr != ptr) { if (block->addr != ptr) {
@ -1476,12 +1463,12 @@ void process_realloc_done(struct process *process, struct mt_msg *mt_msg, void *
struct realloc_entry *re = container_of(it, struct realloc_entry, list); struct realloc_entry *re = container_of(it, struct realloc_entry, list);
if (re->pid == pid) { if (re->pid == pid) {
if (!ptr) if (!ptr && re->addr)
process_rb_insert_block(process, re->addr, re->size, re->stack, re->flags, re->operation); process_rb_insert_block(process, re->addr, re->size, re->stack, re->flags, re->operation);
realloc_del(re); realloc_del(re);
break; return;
} }
} }
@ -1538,8 +1525,10 @@ void process_alloc(struct process *process, struct mt_msg *mt_msg, void *payload
struct rb_stack *stack = stack_add(process, process->pid, stack_data, stack_size, mt_msg->operation); struct rb_stack *stack = stack_add(process, process->pid, stack_data, stack_size, mt_msg->operation);
if (process_rb_insert_block(process, ptr, size, stack, 0, mt_msg->operation)) if (process_rb_insert_block(process, ptr, size, stack, 0, mt_msg->operation)) {
fprintf(stderr, "process_rb_insert_block failed\n");
return; return;
}
process->total_allocations++; process->total_allocations++;
process->bytes_used += size; process->bytes_used += size;

View File

@ -155,7 +155,7 @@ fail:
static void handle_signal(struct task *task) static void handle_signal(struct task *task)
{ {
if (unlikely(options.verbose > 1)) { if (unlikely(options.verbose > 1)) {
if (task->event.e_un.signum && task->event.e_un.signum != SIGSTOP) if (task->event.e_un.signum && (task->event.e_un.signum != SIGSTOP || !task->was_stopped))
fprintf(stderr, "+++ process pid=%d signal %d: %s +++\n", task->pid, task->event.e_un.signum, strsignal(task->event.e_un.signum)); fprintf(stderr, "+++ process pid=%d signal %d: %s +++\n", task->pid, task->event.e_un.signum, strsignal(task->event.e_un.signum));
} }
@ -166,7 +166,6 @@ static void show_exit(struct task *task)
{ {
if (unlikely(options.verbose)) if (unlikely(options.verbose))
fprintf(stderr, "+++ process pid=%d exited (status=%d) +++\n", task->pid, task->event.e_un.ret_val); fprintf(stderr, "+++ process pid=%d exited (status=%d) +++\n", task->pid, task->event.e_un.ret_val);
} }
static void handle_about_exit(struct task *task) static void handle_about_exit(struct task *task)
@ -211,6 +210,9 @@ static void handle_exec(struct task *task)
{ {
debug(DEBUG_FUNCTION, "pid=%d", task->pid); debug(DEBUG_FUNCTION, "pid=%d", task->pid);
if (unlikely(options.verbose))
fprintf(stderr, "+++ process pid=%d exec (%s) +++\n", task->pid, library_execname(task));
if (!options.follow_exec) if (!options.follow_exec)
goto nofollow; goto nofollow;
@ -219,9 +221,6 @@ static void handle_exec(struct task *task)
goto untrace; goto untrace;
} }
if (unlikely(options.verbose))
fprintf(stderr, "+++ process pid=%d exec (%s) +++\n", task->pid, library_execname(task));
continue_task(task, 0); continue_task(task, 0);
return; return;
nofollow: nofollow:

View File

@ -113,11 +113,8 @@ static void report_alloc32(struct task *task, enum mt_operation op, unsigned lon
server_send_msg(op, task->leader->pid, alloc, sizeof(*alloc) + i * sizeof(uint32_t)); server_send_msg(op, task->leader->pid, alloc, sizeof(*alloc) + i * sizeof(uint32_t));
} }
static void report_alloc(struct task *task, enum mt_operation op, unsigned long ptr, unsigned long size, int depth, struct library_symbol *libsym) static void _report_alloc(struct task *task, enum mt_operation op, unsigned long ptr, unsigned long size, int depth, struct library_symbol *libsym)
{ {
if (!ptr)
return;
debug(DEBUG_FUNCTION, "%d [%d]: %#lx %lu", op, task->pid, ptr, size); debug(DEBUG_FUNCTION, "%d [%d]: %#lx %lu", op, task->pid, ptr, size);
if (task_is_64bit(task)) if (task_is_64bit(task))
@ -126,6 +123,14 @@ static void report_alloc(struct task *task, enum mt_operation op, unsigned long
report_alloc32(task, op, ptr, size, depth, libsym); report_alloc32(task, op, ptr, size, depth, libsym);
} }
static void report_alloc(struct task *task, enum mt_operation op, unsigned long ptr, unsigned long size, int depth, struct library_symbol *libsym)
{
if (!ptr)
return;
_report_alloc(task, op, ptr, size, depth, libsym);
}
static void _report_alloc_op(struct task *task, struct library_symbol *libsym, enum mt_operation op) static void _report_alloc_op(struct task *task, struct library_symbol *libsym, enum mt_operation op)
{ {
unsigned long size = fetch_param(task, 0); unsigned long size = fetch_param(task, 0);
@ -203,7 +208,7 @@ static void report_realloc(struct task *task, struct library_symbol *libsym)
{ {
unsigned long addr = fetch_param(task, 0); unsigned long addr = fetch_param(task, 0);
report_alloc(task, MT_REALLOC_ENTER, addr, task->pid, options.sanity ? options.bt_depth : 0, libsym); _report_alloc(task, MT_REALLOC_ENTER, addr, task->pid, options.sanity ? options.bt_depth : 0, libsym);
} }
static void _report_calloc(struct task *task, struct library_symbol *libsym) static void _report_calloc(struct task *task, struct library_symbol *libsym)