mirror of
https://github.com/sstefani/mtrace.git
synced 2025-12-06 16:56:41 +08:00
accurate single step, c++ 11 support, optimizations
This commit is contained in:
parent
e50dccecb3
commit
cf997a7dc9
@ -75,15 +75,18 @@ arch_addr_t get_instruction_pointer(struct task *task);
|
|||||||
void set_instruction_pointer(struct task *task, arch_addr_t addr);
|
void set_instruction_pointer(struct task *task, arch_addr_t addr);
|
||||||
|
|
||||||
/* do a single step */
|
/* do a single step */
|
||||||
int do_singlestep(struct task *task);
|
int do_singlestep(struct task *task, struct breakpoint *bp);
|
||||||
|
|
||||||
/* handle a single step event */
|
/* handle a single step event */
|
||||||
int handle_singlestep(struct task *task, int (*singlestep)(struct task *task));
|
int handle_singlestep(struct task *task, int (*singlestep)(struct task *task), struct breakpoint *bp);
|
||||||
|
|
||||||
/* Find and return caller address, i.e. the address where the current
|
/* Find and return caller address, i.e. the address where the current
|
||||||
* function returns. */
|
* function returns. */
|
||||||
arch_addr_t get_return_addr(struct task *task);
|
arch_addr_t get_return_addr(struct task *task);
|
||||||
|
|
||||||
|
/* get address of IP register */
|
||||||
|
unsigned int ip_reg_addr(void);
|
||||||
|
|
||||||
#if HW_BREAKPOINTS > 0
|
#if HW_BREAKPOINTS > 0
|
||||||
/* returns true if the hw breakpoint is pendig */
|
/* returns true if the hw breakpoint is pendig */
|
||||||
int get_hw_bp_state(struct task *task, unsigned int n);
|
int get_hw_bp_state(struct task *task, unsigned int n);
|
||||||
|
|||||||
@ -291,6 +291,9 @@ void breakpoint_hw_destroy(struct task *task)
|
|||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
|
if (options.nohwbp)
|
||||||
|
return;
|
||||||
|
|
||||||
for(i = 0; i < HW_BREAKPOINTS; ++i)
|
for(i = 0; i < HW_BREAKPOINTS; ++i)
|
||||||
task->hw_bp[i] = NULL;
|
task->hw_bp[i] = NULL;
|
||||||
|
|
||||||
|
|||||||
@ -680,7 +680,7 @@ static int process_rb_insert_block(struct process *process, unsigned long addr,
|
|||||||
if ((addr <= this->addr) && (addr + n > this->addr)) {
|
if ((addr <= this->addr) && (addr + n > this->addr)) {
|
||||||
process_dump_collision(process, this, addr, size, operation);
|
process_dump_collision(process, this, addr, size, operation);
|
||||||
|
|
||||||
if (options.kill)
|
if (unlikely(options.kill))
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1262,7 +1262,7 @@ void process_munmap(struct process *process, struct mt_msg *mt_msg, void *payloa
|
|||||||
if (!is_mmap(block->stack_node->stack->operation)) {
|
if (!is_mmap(block->stack_node->stack->operation)) {
|
||||||
fprintf(stderr, ">>> block missmatch pid:%d MAP<>MALLOC %#lx\n", process->pid, ptr);
|
fprintf(stderr, ">>> block missmatch pid:%d MAP<>MALLOC %#lx\n", process->pid, ptr);
|
||||||
|
|
||||||
if (options.kill)
|
if (unlikely(options.kill))
|
||||||
abort();
|
abort();
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -1387,17 +1387,10 @@ void process_free(struct process *process, struct mt_msg *mt_msg, void *payload)
|
|||||||
|
|
||||||
block = process_rb_search(&process->block_table, ptr);
|
block = process_rb_search(&process->block_table, ptr);
|
||||||
if (block) {
|
if (block) {
|
||||||
if (block->addr != ptr) {
|
|
||||||
fprintf(stderr, ">>> block invalid free %#lx pid:%d\n", ptr, process->pid);
|
|
||||||
|
|
||||||
if (options.kill)
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_mmap(block->stack_node->stack->operation)) {
|
if (is_mmap(block->stack_node->stack->operation)) {
|
||||||
fprintf(stderr, ">>> block missmatch pid:%d MAP<>MALLOC %#lx\n", process->pid, ptr);
|
fprintf(stderr, ">>> block missmatch pid:%d MAP<>MALLOC %#lx\n", process->pid, ptr);
|
||||||
|
|
||||||
if (options.kill)
|
if (unlikely(options.kill))
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1427,10 +1420,10 @@ void process_free(struct process *process, struct mt_msg *mt_msg, void *payload)
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (!process->attached) {
|
if (!process->attached) {
|
||||||
if (unlikely(options.kill)) {
|
fprintf(stderr, ">>> block %#lx not found pid:%d\n", ptr, process->pid);
|
||||||
fprintf(stderr, ">>> block %#lx not found pid:%d\n", ptr, process->pid);
|
|
||||||
|
if (unlikely(options.kill))
|
||||||
abort();
|
abort();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1438,7 +1431,7 @@ void process_free(struct process *process, struct mt_msg *mt_msg, void *payload)
|
|||||||
void process_realloc_done(struct process *process, struct mt_msg *mt_msg, void *payload)
|
void process_realloc_done(struct process *process, struct mt_msg *mt_msg, void *payload)
|
||||||
{
|
{
|
||||||
unsigned long ptr;
|
unsigned long ptr;
|
||||||
unsigned long pid;
|
unsigned int pid;
|
||||||
struct list_head *it;
|
struct list_head *it;
|
||||||
|
|
||||||
if (!process->tracing)
|
if (!process->tracing)
|
||||||
@ -1467,11 +1460,11 @@ void process_realloc_done(struct process *process, struct mt_msg *mt_msg, void *
|
|||||||
process_rb_insert_block(process, re->addr, re->size, re->stack, re->flags, re->operation);
|
process_rb_insert_block(process, re->addr, re->size, re->stack, re->flags, re->operation);
|
||||||
|
|
||||||
realloc_del(re);
|
realloc_del(re);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// fprintf(stderr, ">>> unexpected realloc done pid: %u\n", pid);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1517,7 +1510,7 @@ void process_alloc(struct process *process, struct mt_msg *mt_msg, void *payload
|
|||||||
|
|
||||||
process_dump_collision(process, block, ptr, size, mt_msg->operation);
|
process_dump_collision(process, block, ptr, size, mt_msg->operation);
|
||||||
|
|
||||||
if (options.kill)
|
if (unlikely(options.kill))
|
||||||
abort();
|
abort();
|
||||||
|
|
||||||
process_rb_delete_block(process, block);
|
process_rb_delete_block(process, block);
|
||||||
|
|||||||
2
event.c
2
event.c
@ -312,7 +312,7 @@ static void handle_breakpoint(struct task *task)
|
|||||||
|
|
||||||
save_param_context(task);
|
save_param_context(task);
|
||||||
|
|
||||||
if (libsym->func->report_out || options.kill) {
|
if (libsym->func->report_out || !options.nocpp) {
|
||||||
task->breakpoint = breakpoint_insert(task, get_return_addr(task), NULL, BP_HW_SCRATCH);
|
task->breakpoint = breakpoint_insert(task, get_return_addr(task), NULL, BP_HW_SCRATCH);
|
||||||
if (likely(task->breakpoint)) {
|
if (likely(task->breakpoint)) {
|
||||||
task->libsym = libsym;
|
task->libsym = libsym;
|
||||||
|
|||||||
43
report.c
43
report.c
@ -113,24 +113,19 @@ static void report_alloc32(struct task *task, enum mt_operation op, unsigned lon
|
|||||||
server_send_msg(op, task->leader->pid, alloc, sizeof(*alloc) + i * sizeof(uint32_t));
|
server_send_msg(op, task->leader->pid, alloc, sizeof(*alloc) + i * sizeof(uint32_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _report_alloc(struct task *task, enum mt_operation op, unsigned long ptr, unsigned long size, int depth, struct library_symbol *libsym)
|
static void report_alloc(struct task *task, enum mt_operation op, unsigned long ptr, unsigned long size, int depth, struct library_symbol *libsym)
|
||||||
{
|
{
|
||||||
debug(DEBUG_FUNCTION, "%d [%d]: %#lx %lu", op, task->pid, ptr, size);
|
debug(DEBUG_FUNCTION, "%d [%d]: %#lx %lu", op, task->pid, ptr, size);
|
||||||
|
|
||||||
|
if (!ptr)
|
||||||
|
return;
|
||||||
|
|
||||||
if (task_is_64bit(task))
|
if (task_is_64bit(task))
|
||||||
report_alloc64(task, op, ptr, size, depth, libsym);
|
report_alloc64(task, op, ptr, size, depth, libsym);
|
||||||
else
|
else
|
||||||
report_alloc32(task, op, ptr, size, depth, libsym);
|
report_alloc32(task, op, ptr, size, depth, libsym);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void report_alloc(struct task *task, enum mt_operation op, unsigned long ptr, unsigned long size, int depth, struct library_symbol *libsym)
|
|
||||||
{
|
|
||||||
if (!ptr)
|
|
||||||
return;
|
|
||||||
|
|
||||||
_report_alloc(task, op, ptr, size, depth, libsym);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _report_alloc_op(struct task *task, struct library_symbol *libsym, enum mt_operation op)
|
static void _report_alloc_op(struct task *task, struct library_symbol *libsym, enum mt_operation op)
|
||||||
{
|
{
|
||||||
unsigned long size = fetch_param(task, 0);
|
unsigned long size = fetch_param(task, 0);
|
||||||
@ -186,21 +181,23 @@ static void _report_realloc(struct task *task, struct library_symbol *libsym)
|
|||||||
report_alloc(task, MT_REALLOC, ret, size, options.bt_depth, libsym);
|
report_alloc(task, MT_REALLOC, ret, size, options.bt_depth, libsym);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (task_is_64bit(task)) {
|
if (fetch_param(task, 0)) {
|
||||||
struct mt_alloc_payload_64 *alloc = alloca(sizeof(*alloc));
|
if (task_is_64bit(task)) {
|
||||||
|
struct mt_alloc_payload_64 *alloc = alloca(sizeof(*alloc));
|
||||||
|
|
||||||
alloc->ptr = (uint64_t)ret;
|
alloc->ptr = (uint64_t)ret;
|
||||||
alloc->size = (uint64_t)task->pid;
|
alloc->size = (uint64_t)task->pid;
|
||||||
|
|
||||||
server_send_msg(MT_REALLOC_DONE, task->leader->pid, alloc, sizeof(*alloc));
|
server_send_msg(MT_REALLOC_DONE, task->leader->pid, alloc, sizeof(*alloc));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
struct mt_alloc_payload_32 *alloc = alloca(sizeof(*alloc));
|
struct mt_alloc_payload_32 *alloc = alloca(sizeof(*alloc));
|
||||||
|
|
||||||
alloc->ptr = (uint32_t)ret;
|
alloc->ptr = (uint32_t)ret;
|
||||||
alloc->size = (uint32_t)task->pid;
|
alloc->size = (uint32_t)task->pid;
|
||||||
|
|
||||||
server_send_msg(MT_REALLOC_DONE, task->leader->pid, alloc, sizeof(*alloc));
|
server_send_msg(MT_REALLOC_DONE, task->leader->pid, alloc, sizeof(*alloc));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -208,7 +205,7 @@ static void report_realloc(struct task *task, struct library_symbol *libsym)
|
|||||||
{
|
{
|
||||||
unsigned long addr = fetch_param(task, 0);
|
unsigned long addr = fetch_param(task, 0);
|
||||||
|
|
||||||
_report_alloc(task, MT_REALLOC_ENTER, addr, task->pid, options.sanity ? options.bt_depth : 0, libsym);
|
report_alloc(task, MT_REALLOC_ENTER, addr, task->pid, options.sanity ? options.bt_depth : 0, libsym);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _report_calloc(struct task *task, struct library_symbol *libsym)
|
static void _report_calloc(struct task *task, struct library_symbol *libsym)
|
||||||
@ -368,6 +365,10 @@ static const struct function flist[] = {
|
|||||||
{ "delete[](void*)", "_ZdaPv", 1, report_delete_array, NULL },
|
{ "delete[](void*)", "_ZdaPv", 1, report_delete_array, NULL },
|
||||||
{ "delete(void*, std::nothrow_t const&)", "_ZdlPvRKSt9nothrow_t", 1, report_delete, NULL },
|
{ "delete(void*, std::nothrow_t const&)", "_ZdlPvRKSt9nothrow_t", 1, report_delete, NULL },
|
||||||
{ "delete[](void*, std::nothrow_t const&)", "_ZdaPvRKSt9nothrow_t", 1, report_delete_array, NULL },
|
{ "delete[](void*, std::nothrow_t const&)", "_ZdaPvRKSt9nothrow_t", 1, report_delete_array, NULL },
|
||||||
|
{ "delete(void*, unsigned long)", "_ZdlPvm", 1, report_delete, NULL },
|
||||||
|
{ "delete[](void*, unsigned long)", "_ZdaPvj", 1, report_delete_array, NULL },
|
||||||
|
{ "delete(void*, unsigned long)", "_ZdlPvj", 1, report_delete, NULL },
|
||||||
|
{ "delete[](void*, unsigned long)", "_ZdaPvm", 1, report_delete_array, NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct function *flist_matches_symbol(const char *sym_name)
|
const struct function *flist_matches_symbol(const char *sym_name)
|
||||||
|
|||||||
@ -669,7 +669,7 @@ static int ptrace_cont(struct task *task)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int do_singlestep(struct task *task)
|
int do_singlestep(struct task *task, struct breakpoint *bp)
|
||||||
{
|
{
|
||||||
const uint32_t pc = get_instruction_pointer(task);
|
const uint32_t pc = get_instruction_pointer(task);
|
||||||
uint32_t cpsr;
|
uint32_t cpsr;
|
||||||
@ -714,16 +714,13 @@ int do_singlestep(struct task *task)
|
|||||||
else
|
else
|
||||||
bp2 = NULL;
|
bp2 = NULL;
|
||||||
|
|
||||||
ret = handle_singlestep(task, ptrace_cont);
|
ret = handle_singlestep(task, ptrace_cont, bp);
|
||||||
|
|
||||||
if (bp1)
|
if (bp1)
|
||||||
breakpoint_disable(task, bp1);
|
breakpoint_disable(task, bp1);
|
||||||
if (bp2)
|
if (bp2)
|
||||||
breakpoint_disable(task, bp2);
|
breakpoint_disable(task, bp2);
|
||||||
|
|
||||||
if (ret)
|
return ret;
|
||||||
return ret;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -59,6 +59,11 @@ void set_instruction_pointer(struct task *task, arch_addr_t addr)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int ip_reg_addr(void)
|
||||||
|
{
|
||||||
|
return offsetof(struct pt_regs, ARM_pc);
|
||||||
|
}
|
||||||
|
|
||||||
arch_addr_t get_return_addr(struct task *task)
|
arch_addr_t get_return_addr(struct task *task)
|
||||||
{
|
{
|
||||||
return ARCH_ADDR_T(task->context.regs.ARM_lr);
|
return ARCH_ADDR_T(task->context.regs.ARM_lr);
|
||||||
|
|||||||
@ -74,6 +74,11 @@ void set_instruction_pointer(struct task *task, arch_addr_t addr)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int ip_reg_addr(void)
|
||||||
|
{
|
||||||
|
return sizeof(unsigned long) * PT_NIP;
|
||||||
|
}
|
||||||
|
|
||||||
arch_addr_t get_return_addr(struct task *task)
|
arch_addr_t get_return_addr(struct task *task)
|
||||||
{
|
{
|
||||||
#ifdef __powerpc64__
|
#ifdef __powerpc64__
|
||||||
|
|||||||
@ -233,6 +233,7 @@ static void process_event(struct task *task, int status)
|
|||||||
stop_signal = _process_event(task, status);
|
stop_signal = _process_event(task, status);
|
||||||
|
|
||||||
if (stop_signal == -1) {
|
if (stop_signal == -1) {
|
||||||
|
fprintf(stderr, "%s:%d\n", __FUNCTION__, __LINE__);
|
||||||
task->event.type = EVENT_NONE;
|
task->event.type = EVENT_NONE;
|
||||||
continue_task(task, 0);
|
continue_task(task, 0);
|
||||||
return;
|
return;
|
||||||
@ -245,6 +246,7 @@ static void process_event(struct task *task, int status)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (unlikely(fetch_context(task) == -1)) {
|
if (unlikely(fetch_context(task) == -1)) {
|
||||||
|
fprintf(stderr, "%s:%d\n", __FUNCTION__, __LINE__);
|
||||||
task->event.type = EVENT_NONE;
|
task->event.type = EVENT_NONE;
|
||||||
continue_task(task, 0);
|
continue_task(task, 0);
|
||||||
return;
|
return;
|
||||||
@ -259,7 +261,6 @@ static void process_event(struct task *task, int status)
|
|||||||
if (task->hw_bp[i] && task->hw_bp[i]->addr == ip) {
|
if (task->hw_bp[i] && task->hw_bp[i]->addr == ip) {
|
||||||
if (likely(get_hw_bp_state(task, i)))
|
if (likely(get_hw_bp_state(task, i)))
|
||||||
bp = task->hw_bp[i];
|
bp = task->hw_bp[i];
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -273,8 +274,9 @@ static void process_event(struct task *task, int status)
|
|||||||
{
|
{
|
||||||
bp = breakpoint_find(leader, ip - DECR_PC_AFTER_BREAK);
|
bp = breakpoint_find(leader, ip - DECR_PC_AFTER_BREAK);
|
||||||
if (unlikely(!bp)) {
|
if (unlikely(!bp)) {
|
||||||
task->event.type = EVENT_NONE;
|
fprintf(stderr, "%s:%d\n", __FUNCTION__, __LINE__);
|
||||||
continue_task(task, 0);
|
// task->event.type = EVENT_NONE;
|
||||||
|
// continue_task(task, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#if HW_BREAKPOINTS > 0
|
#if HW_BREAKPOINTS > 0
|
||||||
@ -459,10 +461,12 @@ void stop_threads(struct task *task)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int handle_singlestep(struct task *task, int (*singlestep)(struct task *task))
|
int handle_singlestep(struct task *task, int (*singlestep)(struct task *task), struct breakpoint *bp)
|
||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
int stop_signal;
|
int stop_signal;
|
||||||
|
unsigned long ip;
|
||||||
|
int ret;
|
||||||
|
|
||||||
for(;;) {
|
for(;;) {
|
||||||
if (unlikely(singlestep(task) == -1))
|
if (unlikely(singlestep(task) == -1))
|
||||||
@ -470,26 +474,41 @@ int handle_singlestep(struct task *task, int (*singlestep)(struct task *task))
|
|||||||
|
|
||||||
if (unlikely(TEMP_FAILURE_RETRY(waitpid(task->pid, &status, __WALL)) != task->pid)) {
|
if (unlikely(TEMP_FAILURE_RETRY(waitpid(task->pid, &status, __WALL)) != task->pid)) {
|
||||||
fprintf(stderr, "%s waitpid pid=%d %s\n", __FUNCTION__, task->pid, strerror(errno));
|
fprintf(stderr, "%s waitpid pid=%d %s\n", __FUNCTION__, task->pid, strerror(errno));
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
stop_signal = _process_event(task, status);
|
stop_signal = _process_event(task, status);
|
||||||
|
|
||||||
if (stop_signal == -1)
|
if (stop_signal == -1)
|
||||||
return -1;
|
return 0;
|
||||||
|
|
||||||
if (likely(stop_signal == SIGTRAP))
|
ip = ptrace(PTRACE_PEEKUSER, task->pid, ip_reg_addr(), 0);
|
||||||
return 0; /* check if was a real breakpoint code there */
|
if (ip == (unsigned long)-1) {
|
||||||
|
fprintf(stderr, "%s ptrace get IP pid=%d %s\n", __FUNCTION__, task->pid, strerror(errno));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ip != bp->addr) {
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
|
if (likely(stop_signal == SIGTRAP))
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ret = 1;
|
||||||
|
|
||||||
if (likely(!stop_signal)) {
|
if (likely(!stop_signal)) {
|
||||||
queue_event(task);
|
queue_event(task);
|
||||||
return 0;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fix_signal(task, stop_signal) > 0) {
|
if (fix_signal(task, stop_signal) > 0) {
|
||||||
queue_event(task);
|
queue_event(task);
|
||||||
return 1;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!ret)
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -504,9 +523,9 @@ static int ptrace_singlestep(struct task *task)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int do_singlestep(struct task *task)
|
int do_singlestep(struct task *task, struct breakpoint *bp)
|
||||||
{
|
{
|
||||||
return handle_singlestep(task, ptrace_singlestep);
|
return handle_singlestep(task, ptrace_singlestep, bp);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@ -91,6 +91,15 @@ void set_instruction_pointer(struct task *task, arch_addr_t addr)
|
|||||||
fprintf(stderr, "pid=%d Couldn't set instruction pointer: %s\n", task->pid, strerror(errno));
|
fprintf(stderr, "pid=%d Couldn't set instruction pointer: %s\n", task->pid, strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int ip_reg_addr(void)
|
||||||
|
{
|
||||||
|
#ifdef __x86_64__
|
||||||
|
return sizeof(unsigned long) * RIP;
|
||||||
|
#else
|
||||||
|
return sizeof(unsigned long) * EIP;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
arch_addr_t get_return_addr(struct task *task)
|
arch_addr_t get_return_addr(struct task *task)
|
||||||
{
|
{
|
||||||
long a;
|
long a;
|
||||||
|
|||||||
8
trace.c
8
trace.c
@ -53,19 +53,21 @@ int skip_breakpoint(struct task *task, struct breakpoint *bp)
|
|||||||
int ret = 0;
|
int ret = 0;
|
||||||
struct timespec start;
|
struct timespec start;
|
||||||
|
|
||||||
|
if (task->skip_bp)
|
||||||
|
return 1;
|
||||||
|
|
||||||
if (unlikely(options.verbose > 1))
|
if (unlikely(options.verbose > 1))
|
||||||
start_time(&start);
|
start_time(&start);
|
||||||
|
|
||||||
breakpoint_disable(task, bp);
|
breakpoint_disable(task, bp);
|
||||||
ret = do_singlestep(task);
|
ret = do_singlestep(task, bp);
|
||||||
breakpoint_enable(task, bp);
|
breakpoint_enable(task, bp);
|
||||||
|
|
||||||
if (unlikely(options.verbose > 1))
|
if (unlikely(options.verbose > 1))
|
||||||
set_timer(&start, &skip_bp_time);
|
set_timer(&start, &skip_bp_time);
|
||||||
|
|
||||||
if (unlikely(ret)) {
|
if (unlikely(ret)) {
|
||||||
if (unlikely(ret == 1))
|
task->skip_bp = breakpoint_get(bp);
|
||||||
task->skip_bp = breakpoint_get(bp);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user