mirror of
https://github.com/sstefani/mtrace.git
synced 2025-12-06 16:56:41 +08:00
more accurate single step, prelink fixes, cleanup
This commit is contained in:
parent
cf997a7dc9
commit
3e2980613c
@ -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
|
||||
|
||||
|
||||
12
breakpoint.c
12
breakpoint.c
@ -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;
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
8
main.c
@ -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();
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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
4
task.c
@ -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));
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user