mirror of
https://github.com/sstefani/mtrace.git
synced 2025-12-07 01:06:41 +08:00
fix realloc
This commit is contained in:
parent
3f7f77d105
commit
e50dccecb3
@ -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;
|
||||||
|
|||||||
9
event.c
9
event.c
@ -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:
|
||||||
|
|||||||
15
report.c
15
report.c
@ -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)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user