more accurate single step, prelink fixes, cleanup

This commit is contained in:
Stefani Seibold 2016-05-23 10:27:47 +02:00
parent cf997a7dc9
commit 3e2980613c
11 changed files with 37 additions and 31 deletions

View File

@ -177,7 +177,7 @@ void wait_event_wakeup(void);
int is_64bit(struct mt_elf *mte); int is_64bit(struct mt_elf *mte);
/* change user id of a running process */ /* change user id of a running process */
void change_uid(const char *command); void change_uid(void);
#endif #endif

View File

@ -73,6 +73,9 @@ static void enable_sw_breakpoint(struct task *task, struct breakpoint *bp)
debug(DEBUG_PROCESS, "pid=%d, addr=%#lx", task->pid, bp->addr); debug(DEBUG_PROCESS, "pid=%d, addr=%#lx", task->pid, bp->addr);
copy_from_to_proc(task, bp->addr, break_insn, bp->orig_value, BREAKPOINT_LENGTH); copy_from_to_proc(task, bp->addr, break_insn, bp->orig_value, BREAKPOINT_LENGTH);
bp->break_insn = !memcmp(break_insn, bp->orig_value, BREAKPOINT_LENGTH);
bp->was_hw = 0;
} }
static void disable_sw_breakpoint(struct task *task, const struct breakpoint *bp) static void disable_sw_breakpoint(struct task *task, const struct breakpoint *bp)
@ -230,6 +233,7 @@ void reorder_hw_bp(struct task *task)
bp->hw_bp_slot = i; bp->hw_bp_slot = i;
bp->hw = 1; bp->hw = 1;
bp->was_hw = 1;
each_task(leader, enable_hw_bp_cb, bp); each_task(leader, enable_hw_bp_cb, bp);
@ -260,6 +264,7 @@ static int insert_hw_bp_slot(struct task *task, struct breakpoint *bp)
bp->enabled = 1; bp->enabled = 1;
bp->hw_bp_slot = i; bp->hw_bp_slot = i;
bp->hw = 1; bp->hw = 1;
bp->was_hw = 1;
each_task(leader, enable_hw_bp_cb, bp); each_task(leader, enable_hw_bp_cb, bp);
@ -357,6 +362,7 @@ struct breakpoint *breakpoint_new_ext(struct task *task, arch_addr_t addr, struc
bp->enabled = 0; bp->enabled = 0;
bp->locked = 0; bp->locked = 0;
bp->deleted = 0; bp->deleted = 0;
bp->break_insn = 0;
bp->ext = ext; bp->ext = ext;
bp->refcnt = 1; bp->refcnt = 1;
bp->count = 0; bp->count = 0;
@ -383,6 +389,7 @@ struct breakpoint *breakpoint_new_ext(struct task *task, arch_addr_t addr, struc
case BP_SW: case BP_SW:
memset(bp->orig_value, 0, sizeof(bp->orig_value)); memset(bp->orig_value, 0, sizeof(bp->orig_value));
bp->hw = 0; bp->hw = 0;
bp->was_hw = 0;
} }
if (dict_add(leader->breakpoints, (unsigned long)addr, bp) < 0) { if (dict_add(leader->breakpoints, (unsigned long)addr, bp) < 0) {
@ -505,12 +512,13 @@ void breakpoint_delete(struct task *task, struct breakpoint *bp)
if (unlikely(options.verbose > 1 && bp->libsym)) { if (unlikely(options.verbose > 1 && bp->libsym)) {
fprintf(stderr, fprintf(stderr,
"delete %s breakpoint %s:%s [%#lx] count=%u\n", "delete %s breakpoint %s:%s [%#lx] count=%u was_hw=%u\n",
bp->type == BP_SW ? "sw" : "hw", bp->type == BP_SW ? "sw" : "hw",
bp->libsym->libref->filename, bp->libsym->libref->filename,
bp->libsym->func->demangled_name, bp->libsym->func->demangled_name,
bp->addr, bp->addr,
bp->count); bp->count,
bp->was_hw);
} }
bp->deleted = 1; bp->deleted = 1;

View File

@ -51,6 +51,8 @@ struct breakpoint {
unsigned int locked:1; unsigned int locked:1;
unsigned int deleted:1; unsigned int deleted:1;
unsigned int hw:1; unsigned int hw:1;
unsigned int was_hw:1;
unsigned int break_insn:1;
union { union {
unsigned char orig_value[BREAKPOINT_LENGTH]; unsigned char orig_value[BREAKPOINT_LENGTH];
#if HW_BREAKPOINTS > 0 #if HW_BREAKPOINTS > 0

View File

@ -113,7 +113,7 @@ struct library_symbol *library_symbol_new(struct libref *libref, arch_addr_t add
return libsym; return libsym;
} }
void library_delete(struct task *task, struct library *lib) static void library_delete(struct task *task, struct library *lib)
{ {
if (lib == NULL) if (lib == NULL)
return; return;

View File

@ -101,9 +101,6 @@ struct library {
/* create a new symbol */ /* create a new symbol */
struct library_symbol *library_symbol_new(struct libref *libref, arch_addr_t addr, const struct function *func); struct library_symbol *library_symbol_new(struct libref *libref, arch_addr_t addr, const struct function *func);
/* Delete library. Symbols are destroyed and freed. */
void library_delete(struct task *leader, struct library *lib);
/* Add a library to the list of the thread leader libraries. */ /* Add a library to the list of the thread leader libraries. */
struct library *library_add(struct task *leader, struct libref *libref); struct library *library_add(struct task *leader, struct libref *libref);

8
main.c
View File

@ -104,12 +104,12 @@ static void mtrace_exit(void)
each_pid(remove_task); each_pid(remove_task);
} }
static void mtrace_init(char **cmd) static void mtrace_init(char **cmd_args)
{ {
struct opt_p_t *opt_p_tmp; struct opt_p_t *opt_p_tmp;
if (options.command) { if (options.command) {
struct task *task = task_create(options.command, cmd); struct task *task = task_create(cmd_args);
if (!task) if (!task)
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
@ -138,7 +138,7 @@ static void mtrace_main(void)
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
char **cmd = process_options(argc, argv); char **cmd_args = process_options(argc, argv);
init_pid_hash(); init_pid_hash();
@ -186,7 +186,7 @@ int main(int argc, char *argv[])
if (os_init()) if (os_init())
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
mtrace_init(cmd); mtrace_init(cmd_args);
mtrace_main(); mtrace_main();
mtrace_exit(); mtrace_exit();

View File

@ -315,7 +315,7 @@ finish:
return blocks; return blocks;
} }
void change_uid(const char *command) void change_uid(void)
{ {
uid_t run_uid, run_euid; uid_t run_uid, run_euid;
gid_t run_gid, run_egid; gid_t run_gid, run_egid;
@ -348,13 +348,12 @@ void change_uid(const char *command)
run_egid = run_gid; run_egid = run_gid;
if (!stat(options.command, &statbuf)) { if (!stat(options.command, &statbuf)) {
if (statbuf.st_mode & S_ISUID) { if (statbuf.st_mode & S_ISUID)
run_euid = statbuf.st_uid; run_euid = statbuf.st_uid;
}
if (statbuf.st_mode & S_ISGID) { if (statbuf.st_mode & S_ISGID)
run_egid = statbuf.st_gid; run_egid = statbuf.st_gid;
} }
}
if (setregid(run_gid, run_egid) < 0) { if (setregid(run_gid, run_egid) < 0) {
perror("mtrace-ng: setregid"); perror("mtrace-ng: setregid");
exit(1); exit(1);

View File

@ -462,7 +462,7 @@ static void linkmap_del(struct task *task, struct lt_r_debug_64 *dbg)
addr = ARCH_ADDR_T(rlm.l_next); addr = ARCH_ADDR_T(rlm.l_next);
lib = library_find_with_key(&tmp_list, ARCH_ADDR_T(rlm.l_addr)); lib = library_find_with_key(&tmp_list, ARCH_ADDR_T(rlm.l_ld));
if (lib) if (lib)
list_move_tail(&lib->list, &task->libraries_list); list_move_tail(&lib->list, &task->libraries_list);
} }

View File

@ -466,7 +466,6 @@ int handle_singlestep(struct task *task, int (*singlestep)(struct task *task), s
int status; int status;
int stop_signal; int stop_signal;
unsigned long ip; unsigned long ip;
int ret;
for(;;) { for(;;) {
if (unlikely(singlestep(task) == -1)) if (unlikely(singlestep(task) == -1))
@ -489,26 +488,27 @@ int handle_singlestep(struct task *task, int (*singlestep)(struct task *task), s
} }
if (ip != bp->addr) { if (ip != bp->addr) {
ret = 0; if (likely(stop_signal == SIGTRAP)) {
if (bp->break_insn) {
if (likely(stop_signal == SIGTRAP)) queue_event(task);
return ret; return 1;
}
return 0;
}
} }
else
ret = 1;
if (likely(!stop_signal)) { if (likely(!stop_signal)) {
queue_event(task); queue_event(task);
return ret; return 1;
} }
if (fix_signal(task, stop_signal) > 0) { if (fix_signal(task, stop_signal) > 0) {
queue_event(task); queue_event(task);
return ret; return 1;
} }
if (!ret) if (ip != bp->addr)
return ret; return 0;
} }
} }

4
task.c
View File

@ -305,7 +305,7 @@ fail:
return -1; return -1;
} }
struct task *task_create(const char *command, char **argv) struct task *task_create(char **argv)
{ {
struct task *task; struct task *task;
pid_t pid; pid_t pid;
@ -319,7 +319,7 @@ struct task *task_create(const char *command, char **argv)
} }
if (!pid) { /* child */ if (!pid) { /* child */
change_uid(options.command); change_uid();
trace_me(); trace_me();
execvp(options.command, argv); execvp(options.command, argv);
fprintf(stderr, "Can't execute `%s': %s\n", options.command, strerror(errno)); fprintf(stderr, "Can't execute `%s': %s\n", options.command, strerror(errno));

2
task.h
View File

@ -119,7 +119,7 @@ int process_exec(struct task *task);
struct task *task_new(pid_t pid); struct task *task_new(pid_t pid);
struct task *task_create(const char *command, char **argv); struct task *task_create(char **argv);
void open_pid(pid_t pid); void open_pid(pid_t pid);