From 046b2003dcf15b4227781a07331402f2760a4bc6 Mon Sep 17 00:00:00 2001 From: Stefani Seibold Date: Thu, 14 May 2015 18:45:35 +0200 Subject: [PATCH] misc fixes fix sortby function removed not longer needed sigchld handler fix interactive mode add verbose level 2 for library trace output --- client/client.c | 27 ++++++++++++++++++++++++--- client/process.c | 16 +++++++++++----- client/readline.c | 18 +++++++++++------- client/readline.h | 1 + library.c | 9 ++++++++- main.c | 12 +++++++----- mtelf.c | 24 +++++++++++++----------- sysdeps/linux-gnu/os.c | 32 +++++++------------------------- 8 files changed, 82 insertions(+), 57 deletions(-) diff --git a/client/client.c b/client/client.c index 6e22757..2470e5a 100644 --- a/client/client.c +++ b/client/client.c @@ -42,6 +42,7 @@ #include "client.h" #include "dump.h" #include "ioevent.h" +#include "main.h" #include "options.h" #include "process.h" #include "readline.h" @@ -592,7 +593,8 @@ static int signal_func(void) { fprintf(stderr, "terminating...\n"); client_iterate_processes(scan_process); - exit(0); + client_close(); + return -1; } int client_start(void) @@ -624,10 +626,15 @@ int client_start(void) ioevent_add_input(client_fd, client_func); if (options.interactive) { + signal(SIGINT, SIG_IGN); + signal(SIGTERM, SIG_IGN); + readline_init(); while(ioevent_watch(-1) != -1) ; + + readline_exit(); } else { if (pipe(pipefd) == -1) { @@ -651,8 +658,22 @@ int client_start(void) void *client_thread(void *unused) { - while(client_fd != -1) - client_func(); + if (options.interactive) { + ioevent_add_input(client_fd, client_func); + + readline_init(); + + while(ioevent_watch(-1) != -1) + ; + + readline_exit(); + + mtrace_request_exit(); + } + else { + while(client_fd != -1) + client_func(); + } return NULL; } diff --git a/client/process.c b/client/process.c index 688dbd3..050ff50 100644 --- a/client/process.c +++ b/client/process.c @@ -617,7 +617,7 @@ static int process_rb_insert_block(struct process *process, unsigned long addr, parent = *new; if (addr <= this->addr && addr + n > this->addr) { - if (options.kill || options.verbose > 1) { + if (options.kill || options.verbose > 2) { process_dump_collision(process, this, addr, size, operation); if (options.kill) @@ -1128,7 +1128,7 @@ void process_munmap(struct process *process, struct mt_msg *mt_msg, void *payloa break; if (!is_mmap(block->stack_node->stack->operation)) { - if (options.kill || options.verbose > 1) { + if (options.kill || options.verbose > 2) { fprintf(stderr, ">>> block missmatch pid:%d MAP<>MALLOC %#lx\n", process->pid, ptr); if (options.kill) @@ -1213,7 +1213,7 @@ void process_free(struct process *process, struct mt_msg *mt_msg, void *payload) block = process_rb_search(&process->block_table, ptr); if (block) { if (is_mmap(block->stack_node->stack->operation)) { - if (options.kill || options.verbose > 1) { + if (options.kill || options.verbose > 2) { fprintf(stderr, ">>> block missmatch pid:%d MAP<>MALLOC %#lx\n", process->pid, ptr); if (options.kill) @@ -1224,7 +1224,7 @@ void process_free(struct process *process, struct mt_msg *mt_msg, void *payload) } else { if (!process->attached) { - if (options.kill || options.verbose > 1) { + if (options.kill || options.verbose > 2) { fprintf(stderr, ">>> block %#lx not found pid:%d tid:%d\n", ptr, process->pid, mt_msg->tid); if (options.kill) @@ -1271,7 +1271,7 @@ void process_alloc(struct process *process, struct mt_msg *mt_msg, void *payload block = process_rb_search_range(&process->block_table, ptr, size); if (block) { - if (options.kill || options.verbose > 1) { + if (options.kill || options.verbose > 2) { process_dump_collision(process, block, ptr, size, mt_msg->operation); if (options.kill) @@ -1321,6 +1321,12 @@ void process_dump_sortby(struct process *process) case OPT_SORT_AVERAGE: _process_dump(process, sort_average, skip_zero_allocations, options.output); break; + case OPT_SORT_BYTES_LEAKED: + _process_dump(process, sort_bytes_leaked, skip_zero_leaks, options.output); + break; + case OPT_SORT_LEAKS: + _process_dump(process, sort_leaks, skip_zero_leaks, options.output); + break; case OPT_SORT_STACKS: _process_dump(process, sort_allocations, skip_none, options.output); break; diff --git a/client/readline.c b/client/readline.c index 5e3bf2c..f2eedb5 100644 --- a/client/readline.c +++ b/client/readline.c @@ -86,6 +86,7 @@ const char status_str[] = "status"; const char stop_str[] = "stop"; static const char *outfile; +static int quit; static struct cmd_opt dump_opts[] = { { "allocations", 2, process_dump_sort_allocations, "sort by number of open allocations" }, @@ -203,12 +204,6 @@ static struct cmd_opt cmds[] = { { }, }; -static void _quit(void) -{ - rl_callback_handler_remove(); - _exit(1); -} - static inline char *skip_spaces(const char *s) { while(isspace(*s)) @@ -663,7 +658,7 @@ static int do_proclist(struct cmd_opt *cmd, int argc, const char *argv[]) static int do_quit(struct cmd_opt *cmd, int argc, const char *argv[]) { - _quit(); + quit = 1; return 0; } @@ -826,6 +821,10 @@ static int do_stop(struct cmd_opt *cmd, int argc, const char *argv[]) static int readline_func(void) { rl_callback_read_char(); + + if (quit) + return -1; + return 0; } @@ -857,3 +856,8 @@ void readline_init(void) ioevent_add_input(0, readline_func); } +void readline_exit(void) +{ + rl_callback_handler_remove(); +} + diff --git a/client/readline.h b/client/readline.h index a74c4b9..459713a 100644 --- a/client/readline.h +++ b/client/readline.h @@ -24,6 +24,7 @@ #define _INC_CLIENT_READLINE_H void readline_init(void); +void readline_exit(void); #endif diff --git a/library.c b/library.c index 4581b66..498f5ea 100644 --- a/library.c +++ b/library.c @@ -33,6 +33,7 @@ #include "debug.h" #include "dict.h" #include "library.h" +#include "options.h" #include "report.h" #include "server.h" #include "task.h" @@ -202,6 +203,9 @@ void library_delete_list(struct task *leader, struct list_head *list) debug(DEBUG_FUNCTION, "%s@%#lx", lib->filename, lib->base); + if (options.verbose > 1) + fprintf(stderr, "+++ library del pid=%d %s@%#lx %#lx-%#lx +++\n", leader->pid, lib->filename, lib->base, lib->load_addr, lib->load_addr + lib->load_size); + library_destroy(leader, lib); } } @@ -220,7 +224,7 @@ static void cb_breakpoint_for_symbol(struct library_symbol *libsym, void *data) } bp = breakpoint_new(task, addr, libsym, libsym->func->hw_bp_min <= HW_BREAKPOINTS ? HW_BP : SW_BP); if (!bp) - fprintf(stderr, "Couldn't insert breakpoint for %s to %d: %s.", libsym->func->name, task->pid, strerror(errno)); + fprintf(stderr, "Couldn't insert breakpoint for %s to %d: %s", libsym->func->name, task->pid, strerror(errno)); if (server_connected()) breakpoint_enable(task, bp); @@ -232,6 +236,9 @@ void library_add(struct task *leader, struct library *lib) debug(DEBUG_PROCESS, "%s@%#lx to pid=%d", lib->filename, lib->base, leader->pid); + if (options.verbose > 1) + fprintf(stderr, "+++ library add pid=%d %s@%#lx %#lx-%#lx +++\n", leader->pid, lib->filename, lib->base, lib->load_addr, lib->load_addr + lib->load_size); + /* Insert breakpoints for all active symbols. */ library_each_symbol(lib, cb_breakpoint_for_symbol, leader); diff --git a/main.c b/main.c index b0649e8..932a35f 100644 --- a/main.c +++ b/main.c @@ -86,12 +86,14 @@ static void dump_process(struct task *leader) static void mtrace_exit(void) { - each_process(stop_threads); + if (!options.interactive) { + each_process(stop_threads); - while(server_connected()) { - if (task_list_empty()) - break; - dump_process(get_first_process()); + while(server_connected()) { + if (task_list_empty()) + break; + dump_process(get_first_process()); + } } each_process(remove_proc); diff --git a/mtelf.c b/mtelf.c index fc12e1e..0281a96 100644 --- a/mtelf.c +++ b/mtelf.c @@ -75,8 +75,10 @@ static int open_elf(struct mt_elf *mte, struct task *task, const char *filename) mte->fd = open(filename, O_RDONLY); } - if (mte->fd == -1) - return 1; + if (mte->fd == -1) { + fprintf(stderr, "could not open %s\n", filename); + return -1; + } elf_version(EV_CURRENT); @@ -88,17 +90,17 @@ static int open_elf(struct mt_elf *mte, struct task *task, const char *filename) if (mte->elf == NULL || elf_kind(mte->elf) != ELF_K_ELF) { fprintf(stderr, "\"%s\" is not an ELF file\n", filename); - exit(EXIT_FAILURE); + return -1; } if (gelf_getehdr(mte->elf, &mte->ehdr) == NULL) { fprintf(stderr, "can't read ELF header of \"%s\": %s\n", filename, elf_errmsg(-1)); - exit(EXIT_FAILURE); + return -1; } if (mte->ehdr.e_type != ET_EXEC && mte->ehdr.e_type != ET_DYN) { fprintf(stderr, "\"%s\" is neither an ELF executable" " nor a shared library\n", filename); - exit(EXIT_FAILURE); + return -1; } if (1 @@ -113,7 +115,7 @@ static int open_elf(struct mt_elf *mte, struct task *task, const char *filename) #endif ) { fprintf(stderr, "\"%s\" is ELF from incompatible architecture\n", filename); - exit(EXIT_FAILURE); + return -1; } return 0; @@ -320,13 +322,13 @@ static int elf_read(struct mt_elf *mte, struct task *task, const char *filename, scn = elf_getscn(mte->elf, i); if (scn == NULL || gelf_getshdr(scn, &shdr) == NULL) { fprintf(stderr, "Couldn't get section #%d from" " \"%s\": %s\n", i, filename, elf_errmsg(-1)); - exit(EXIT_FAILURE); + return -1; } name = elf_strptr(mte->elf, mte->ehdr.e_shstrndx, shdr.sh_name); if (name == NULL) { fprintf(stderr, "Couldn't get name of section #%d from \"%s\": %s\n", i, filename, elf_errmsg(-1)); - exit(EXIT_FAILURE); + return -1; } if (shdr.sh_type == SHT_SYMTAB) { @@ -341,7 +343,7 @@ static int elf_read(struct mt_elf *mte, struct task *task, const char *filename, data = elf_getdata(scn, NULL); if (data == NULL) { fprintf(stderr, "Couldn't get .dynamic data from \"%s\": %s\n", filename, strerror(errno)); - exit(EXIT_FAILURE); + return -1; } for(idx = 0; gelf_getdyn(data, idx, &dyn); ++idx) { @@ -357,12 +359,12 @@ static int elf_read(struct mt_elf *mte, struct task *task, const char *filename, if (!mte->dyn_addr) { fprintf(stderr, "Couldn't find .dynamic section \"%s\"\n", filename); - exit(EXIT_FAILURE); + return -1; } if (!mte->dynsym || !mte->dynstr) { fprintf(stderr, "Couldn't find .dynsym or .dynstr in \"%s\"\n", filename); - exit(EXIT_FAILURE); + return -1; } return 0; diff --git a/sysdeps/linux-gnu/os.c b/sysdeps/linux-gnu/os.c index 678b8ea..fb0adaa 100644 --- a/sysdeps/linux-gnu/os.c +++ b/sysdeps/linux-gnu/os.c @@ -148,10 +148,6 @@ static void signal_exit(int sig) mtrace_request_exit(); } -static void sigchld_handler(int signum) -{ -} - static int open_mem(pid_t pid) { int h; @@ -389,11 +385,9 @@ ssize_t sock_fd_write(int sock, void *buf, ssize_t buflen, int fd) int os_init(void) { - sigset_t block_sigset; struct sigaction act; const int siglist[] = { SIGSEGV, SIGABRT, SIGTRAP, SIGILL, SIGFPE }; unsigned int i; - int ret; for(i = 0; i < ARRAY_SIZE(siglist); i++) { act.sa_flags = SA_ONESHOT | SA_SIGINFO; @@ -402,26 +396,14 @@ int os_init(void) sigaction(siglist[i], &act, NULL); } - signal(SIGINT, signal_exit); /* Detach task_es when interrupted */ - signal(SIGTERM, signal_exit); /* ... or killed */ + /* Detach task_es when interrupted */ + if (options.interactive) + signal(SIGINT, SIG_IGN); + else + signal(SIGINT, signal_exit); - sigemptyset(&act.sa_mask); - act.sa_flags = SA_RESTART; - act.sa_handler = sigchld_handler; - - if (sigaction(SIGCHLD, &act, NULL)) { - perror("sigaction(SIGCHLD)"); - return -1; - } - - sigemptyset(&block_sigset); - sigaddset(&block_sigset, SIGCHLD); - - ret = pthread_sigmask(SIG_BLOCK, &block_sigset, NULL); - if (ret) { - fprintf(stderr, "pthread_sigmask %d (%s)\n", ret, strerror(ret)); - return -1; - } + /* ... or killed */ + signal(SIGTERM, signal_exit); return 0; }