mirror of
https://github.com/sstefani/mtrace.git
synced 2025-12-06 16:56:41 +08:00
commit
237bf3aa60
@ -604,7 +604,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 ((this->addr <= addr) && (this->addr + this->size > addr))
|
||||||
return this;
|
return this;
|
||||||
|
|
||||||
if (addr < this->addr)
|
if (addr < this->addr)
|
||||||
@ -1298,20 +1298,32 @@ void process_munmap(struct process *process, struct mt_msg *mt_msg, void *payloa
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
block = process_rb_search_range(&process->block_table, ptr, size);
|
block = process_rb_search_range(&process->block_table, ptr, size);
|
||||||
if (!block)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (!is_mmap(block->stack_node->stack->operation)) {
|
if (block && !is_mmap(block->stack_node->stack->operation)) {
|
||||||
if (unlikely(options.kill)) {
|
// ignore blocks not mmap'ed
|
||||||
fprintf(stderr, ">>> block missmatch pid:%d MAP<>MALLOC %#lx\n", process->pid, ptr);
|
block = NULL;
|
||||||
abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!block) {
|
||||||
|
// printf("## no block found for %lx, %ld. Trying next page\n", ptr, size);
|
||||||
|
// it is legal to unmap arbitrary addresses, so ptr might be actually before the mmap and it might span muplitple mmaps areas.
|
||||||
|
// so we'll might need to search our blocks.
|
||||||
|
// eg this is legal: void* p=mmap(0,512*1024, PROT_WRITE|PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); munmap(p+4096,4096); munmap(p-4096, 512*1024+4096);
|
||||||
|
// FIXME pagesize is hardcoded as 4096 bytes, which should be safe (AFAIK 4k is the minimum "out there".) A more efficient way would be to transmit
|
||||||
|
// the target's PAGE_SIZE on startup.
|
||||||
|
if (size > 4096) {
|
||||||
|
size -= 4096;
|
||||||
|
ptr += 4096;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ptr in block -- this is already checked.
|
||||||
if (block->addr >= ptr) {
|
if (block->addr >= ptr) {
|
||||||
unsigned off = block->addr - ptr;
|
unsigned long off = block->addr - ptr;
|
||||||
|
|
||||||
size -= off;
|
size -= off;
|
||||||
ptr += off;
|
ptr += off;
|
||||||
@ -1331,33 +1343,32 @@ void process_munmap(struct process *process, struct mt_msg *mt_msg, void *payloa
|
|||||||
process_rb_delete_block(process, block);
|
process_rb_delete_block(process, block);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
unsigned off = ptr - block->addr;
|
unsigned long off = ptr - block->addr;
|
||||||
|
|
||||||
if (off + size < block->size) {
|
if (off + size < block->size) {
|
||||||
unsigned long new_addr = block->addr + (off + size);
|
unsigned long new_addr = block->addr + (off + size);
|
||||||
unsigned long new_size = block->size - (off + size);
|
unsigned long new_size = block->size - (off + size);
|
||||||
|
|
||||||
process_release_mem(process, block, block->size - off - new_size);
|
process_release_mem(process, block, block->size - off);
|
||||||
|
|
||||||
block->size = off;
|
block->size = off;
|
||||||
|
|
||||||
if (process_rb_insert_block(process, new_addr, new_size, block->stack_node, 0, mt_msg->operation))
|
if (process_rb_insert_block(process, new_addr, new_size, block->stack_node, 0, mt_msg->operation))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
process->n_allocations++;
|
|
||||||
process->total_allocations++;
|
process->total_allocations++;
|
||||||
process->bytes_used += new_size;
|
process->bytes_used += new_size;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
// freeing a chunk at the end of the mmap block.
|
||||||
|
size_t amount_freed = block->size - off;
|
||||||
|
process_release_mem(process, block, amount_freed);
|
||||||
|
|
||||||
process_release_mem(process, block, off);
|
block->size -= amount_freed;
|
||||||
|
size -= amount_freed ;
|
||||||
block->addr += off;
|
ptr += amount_freed;
|
||||||
block->size -= off;
|
}
|
||||||
|
|
||||||
size -= block->size;
|
|
||||||
ptr += block->size;
|
|
||||||
}
|
}
|
||||||
} while(size);
|
} while(size);
|
||||||
}
|
}
|
||||||
@ -1489,7 +1500,7 @@ void process_free(struct process *process, struct mt_msg *mt_msg, void *payload)
|
|||||||
void process_realloc_done(struct process *process, struct mt_msg *mt_msg, void *payload)
|
void process_realloc_done(struct process *process, struct mt_msg *mt_msg, void *payload)
|
||||||
{
|
{
|
||||||
unsigned long ptr;
|
unsigned long ptr;
|
||||||
unsigned int pid;
|
unsigned long pid;
|
||||||
struct list_head *it;
|
struct list_head *it;
|
||||||
|
|
||||||
(void)mt_msg;
|
(void)mt_msg;
|
||||||
@ -1525,7 +1536,7 @@ void process_realloc_done(struct process *process, struct mt_msg *mt_msg, void *
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (unlikely(options.kill)) {
|
if (unlikely(options.kill)) {
|
||||||
fprintf(stderr, ">>> unexpected realloc done pid: %u ptr: %#lx\n", pid, ptr);
|
fprintf(stderr, ">>> unexpected realloc done pid: %lu ptr: %#lx\n", pid, ptr);
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|||||||
51
report.c
51
report.c
@ -241,6 +241,9 @@ static void _report_calloc(struct task *task, struct library_symbol *libsym)
|
|||||||
report_alloc(task, MT_MALLOC, ret, size, options.bt_depth, libsym);
|
report_alloc(task, MT_MALLOC, ret, size, options.bt_depth, libsym);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static ssize_t arch_pagesize = -1;
|
||||||
|
|
||||||
static void _report_mmap(struct task *task, struct library_symbol *libsym)
|
static void _report_mmap(struct task *task, struct library_symbol *libsym)
|
||||||
{
|
{
|
||||||
unsigned long ret = fetch_retval(task);
|
unsigned long ret = fetch_retval(task);
|
||||||
@ -249,6 +252,11 @@ static void _report_mmap(struct task *task, struct library_symbol *libsym)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
unsigned long size = fetch_param(task, 1);
|
unsigned long size = fetch_param(task, 1);
|
||||||
|
if (unlikely(arch_pagesize==-1)) arch_pagesize=getpagesize();
|
||||||
|
// fixup size, if size is not a multiple of the pagesize, we get the "partial" page too. -
|
||||||
|
if (size % arch_pagesize) {
|
||||||
|
size += arch_pagesize - size % arch_pagesize;
|
||||||
|
}
|
||||||
|
|
||||||
report_alloc(task, MT_MMAP, ret, size, options.bt_depth, libsym);
|
report_alloc(task, MT_MMAP, ret, size, options.bt_depth, libsym);
|
||||||
}
|
}
|
||||||
@ -277,17 +285,34 @@ static void _report_mmap64(struct task *task, struct library_symbol *libsym)
|
|||||||
else
|
else
|
||||||
size.l = fetch_param(task, 1);
|
size.l = fetch_param(task, 1);
|
||||||
|
|
||||||
|
if (unlikely(arch_pagesize == -1)) arch_pagesize=getpagesize();
|
||||||
|
// fixup size, if size is not a multiple of the pagesize, we get the "partial" page too. -
|
||||||
|
if (size.l % arch_pagesize) {
|
||||||
|
size.l += arch_pagesize - size.l % arch_pagesize;
|
||||||
|
}
|
||||||
|
|
||||||
report_alloc(task, MT_MMAP64, ret, size.l, options.bt_depth, libsym);
|
report_alloc(task, MT_MMAP64, ret, size.l, options.bt_depth, libsym);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void report_munmap(struct task *task, struct library_symbol *libsym)
|
static void _report_munmap(struct task *task, struct library_symbol *libsym)
|
||||||
{
|
{
|
||||||
unsigned long addr = fetch_param(task, 0);
|
unsigned long addr = fetch_param(task, 0);
|
||||||
unsigned long size = fetch_param(task, 1);
|
unsigned long size = fetch_param(task, 1);
|
||||||
|
unsigned long ret = fetch_retval(task);
|
||||||
|
|
||||||
|
if(ret != 0 ) return;
|
||||||
|
|
||||||
|
if(unlikely(arch_pagesize==-1)) arch_pagesize=getpagesize();
|
||||||
|
|
||||||
|
// fixup size, if needed: all pages in [addr, addr+size] are unmapped -- see munmap(2)
|
||||||
|
if(size % arch_pagesize) {
|
||||||
|
size += arch_pagesize - size % arch_pagesize;
|
||||||
|
}
|
||||||
|
|
||||||
report_alloc(task, MT_MUNMAP, addr, size, 0, libsym);
|
report_alloc(task, MT_MUNMAP, addr, size, 0, libsym);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void _report_memalign(struct task *task, struct library_symbol *libsym)
|
static void _report_memalign(struct task *task, struct library_symbol *libsym)
|
||||||
{
|
{
|
||||||
unsigned long size = fetch_param(task, 1);
|
unsigned long size = fetch_param(task, 1);
|
||||||
@ -344,20 +369,20 @@ static void _report_pvalloc(struct task *task, struct library_symbol *libsym)
|
|||||||
return report_alloc(task, MT_PVALLOC, ret, size, options.bt_depth, libsym);
|
return report_alloc(task, MT_PVALLOC, ret, size, options.bt_depth, libsym);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void report_mremap(struct task *task, struct library_symbol *libsym)
|
|
||||||
{
|
|
||||||
unsigned long addr = fetch_param(task, 0);
|
|
||||||
unsigned long size = fetch_param(task, 1);
|
|
||||||
|
|
||||||
report_alloc(task, MT_MUNMAP, addr, size, 0, libsym);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _report_mremap(struct task *task, struct library_symbol *libsym)
|
static void _report_mremap(struct task *task, struct library_symbol *libsym)
|
||||||
{
|
{
|
||||||
unsigned long size = fetch_param(task, 2);
|
unsigned long addr = fetch_param(task, 0);
|
||||||
|
unsigned long oldsize = fetch_param(task, 1);
|
||||||
|
|
||||||
|
unsigned long newsize = fetch_param(task, 2);
|
||||||
unsigned long ret = fetch_retval(task);
|
unsigned long ret = fetch_retval(task);
|
||||||
|
|
||||||
report_alloc(task, MT_MMAP, ret, size, options.bt_depth, libsym);
|
if( (void*)ret != MAP_FAILED) {
|
||||||
|
// mremap(2): if oldsize is zero and the mapping a shared mapping, a new mapping
|
||||||
|
// (Of the existing) will be created.
|
||||||
|
if (oldsize) report_alloc(task, MT_MUNMAP, addr, oldsize, 0, libsym);
|
||||||
|
report_alloc(task, MT_MMAP, ret, newsize, options.bt_depth, libsym);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct function flist[] = {
|
static const struct function flist[] = {
|
||||||
@ -368,12 +393,12 @@ static const struct function flist[] = {
|
|||||||
{ "posix_memalign", "posix_memalign", 0, NULL, _report_posix_memalign },
|
{ "posix_memalign", "posix_memalign", 0, NULL, _report_posix_memalign },
|
||||||
{ "mmap", "mmap", 0, NULL, _report_mmap },
|
{ "mmap", "mmap", 0, NULL, _report_mmap },
|
||||||
{ "mmap64", "mmap64", 1, NULL, _report_mmap64 },
|
{ "mmap64", "mmap64", 1, NULL, _report_mmap64 },
|
||||||
{ "munmap", "munmap", 0, report_munmap, NULL },
|
{ "munmap", "munmap", 0, NULL, _report_munmap },
|
||||||
{ "memalign", "memalign", 0, NULL, _report_memalign },
|
{ "memalign", "memalign", 0, NULL, _report_memalign },
|
||||||
{ "aligned_alloc", "aligned_alloc", 1, NULL, _report_aligned_alloc },
|
{ "aligned_alloc", "aligned_alloc", 1, NULL, _report_aligned_alloc },
|
||||||
{ "valloc", "valloc", 1, NULL, _report_valloc },
|
{ "valloc", "valloc", 1, NULL, _report_valloc },
|
||||||
{ "pvalloc", "pvalloc", 1, NULL, _report_pvalloc },
|
{ "pvalloc", "pvalloc", 1, NULL, _report_pvalloc },
|
||||||
{ "mremap", "mremap", 0, report_mremap, _report_mremap },
|
{ "mremap", "mremap", 0, NULL, _report_mremap },
|
||||||
{ "cfree", "cfree", 1, report_free, NULL },
|
{ "cfree", "cfree", 1, report_free, NULL },
|
||||||
{ "reallocarray", "reallocarray", 0, NULL, _report_reallocarray },
|
{ "reallocarray", "reallocarray", 0, NULL, _report_reallocarray },
|
||||||
#if 0
|
#if 0
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user