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);
/* change user id of a running process */
void change_uid(const char *command);
void change_uid(void);
#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);
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)
@ -230,6 +233,7 @@ void reorder_hw_bp(struct task *task)
bp->hw_bp_slot = i;
bp->hw = 1;
bp->was_hw = 1;
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->hw_bp_slot = i;
bp->hw = 1;
bp->was_hw = 1;
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->locked = 0;
bp->deleted = 0;
bp->break_insn = 0;
bp->ext = ext;
bp->refcnt = 1;
bp->count = 0;
@ -383,6 +389,7 @@ struct breakpoint *breakpoint_new_ext(struct task *task, arch_addr_t addr, struc
case BP_SW:
memset(bp->orig_value, 0, sizeof(bp->orig_value));
bp->hw = 0;
bp->was_hw = 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)) {
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->libsym->libref->filename,
bp->libsym->func->demangled_name,
bp->addr,
bp->count);
bp->count,
bp->was_hw);
}
bp->deleted = 1;

View File

@ -51,6 +51,8 @@ struct breakpoint {
unsigned int locked:1;
unsigned int deleted:1;
unsigned int hw:1;
unsigned int was_hw:1;
unsigned int break_insn:1;
union {
unsigned char orig_value[BREAKPOINT_LENGTH];
#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;
}
void library_delete(struct task *task, struct library *lib)
static void library_delete(struct task *task, struct library *lib)
{
if (lib == NULL)
return;

View File

@ -101,9 +101,6 @@ struct library {
/* create a new symbol */
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. */
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);
}
static void mtrace_init(char **cmd)
static void mtrace_init(char **cmd_args)
{
struct opt_p_t *opt_p_tmp;
if (options.command) {
struct task *task = task_create(options.command, cmd);
struct task *task = task_create(cmd_args);
if (!task)
exit(EXIT_FAILURE);
@ -138,7 +138,7 @@ static void mtrace_main(void)
int main(int argc, char *argv[])
{
char **cmd = process_options(argc, argv);
char **cmd_args = process_options(argc, argv);
init_pid_hash();
@ -186,7 +186,7 @@ int main(int argc, char *argv[])
if (os_init())
exit(EXIT_FAILURE);
mtrace_init(cmd);
mtrace_init(cmd_args);
mtrace_main();
mtrace_exit();

View File

@ -315,7 +315,7 @@ finish:
return blocks;
}
void change_uid(const char *command)
void change_uid(void)
{
uid_t run_uid, run_euid;
gid_t run_gid, run_egid;
@ -348,13 +348,12 @@ void change_uid(const char *command)
run_egid = run_gid;
if (!stat(options.command, &statbuf)) {
if (statbuf.st_mode & S_ISUID) {
if (statbuf.st_mode & S_ISUID)
run_euid = statbuf.st_uid;
}
if (statbuf.st_mode & S_ISGID) {
if (statbuf.st_mode & S_ISGID)
run_egid = statbuf.st_gid;
}
}
if (setregid(run_gid, run_egid) < 0) {
perror("mtrace-ng: setregid");
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);
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)
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 stop_signal;
unsigned long ip;
int ret;
for(;;) {
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) {
ret = 0;
if (likely(stop_signal == SIGTRAP))
return ret;
if (likely(stop_signal == SIGTRAP)) {
if (bp->break_insn) {
queue_event(task);
return 1;
}
return 0;
}
}
else
ret = 1;
if (likely(!stop_signal)) {
queue_event(task);
return ret;
return 1;
}
if (fix_signal(task, stop_signal) > 0) {
queue_event(task);
return ret;
return 1;
}
if (!ret)
return ret;
if (ip != bp->addr)
return 0;
}
}

4
task.c
View File

@ -305,7 +305,7 @@ fail:
return -1;
}
struct task *task_create(const char *command, char **argv)
struct task *task_create(char **argv)
{
struct task *task;
pid_t pid;
@ -319,7 +319,7 @@ struct task *task_create(const char *command, char **argv)
}
if (!pid) { /* child */
change_uid(options.command);
change_uid();
trace_me();
execvp(options.command, argv);
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_create(const char *command, char **argv);
struct task *task_create(char **argv);
void open_pid(pid_t pid);