misc fixes

fix sortby function
removed not longer needed sigchld handler
fix interactive mode
add verbose level 2 for library trace output
This commit is contained in:
Stefani Seibold 2015-05-14 18:45:35 +02:00
parent 04aa768634
commit 046b2003dc
8 changed files with 82 additions and 57 deletions

View File

@ -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;
}

View File

@ -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;

View File

@ -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();
}

View File

@ -24,6 +24,7 @@
#define _INC_CLIENT_READLINE_H
void readline_init(void);
void readline_exit(void);
#endif

View File

@ -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);

12
main.c
View File

@ -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);

24
mtelf.c
View File

@ -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;

View File

@ -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;
}