Example #1
0
void
db_delete_breakpoint(
	task_t		task,
	db_addr_t	addr,
	vm_offset_t	task_thd)
{
	register db_breakpoint_t	bkpt;
	register db_breakpoint_t	*prev;

	for (prev = &db_breakpoint_list; (bkpt = *prev) != 0;
					     prev = &bkpt->link) {
	    if ((bkpt->task == task
		   || (task != TASK_NULL && (bkpt->flags & BKPT_USR_GLOBAL)))
		&& bkpt->address == addr)
		break;
	}
	if (bkpt && (bkpt->flags & BKPT_SET_IN_MEM)) {
	    db_printf("cannot delete it now.\n");
	    return;
	}
	if (bkpt == 0
	    || db_delete_thread_breakpoint(bkpt, task_thd) < 0) {
	    db_printf("Not set.\n");
	    return;
	}
	if (bkpt->threads == 0) {
	    *prev = bkpt->link;
	    db_breakpoint_free(bkpt);
	}
}
Example #2
0
/*
 * Set a temporary breakpoint.
 * The instruction is changed immediately,
 * so the breakpoint does not have to be on the breakpoint list.
 */
db_breakpoint_t
db_set_temp_breakpoint(
	task_t		task,
	db_addr_t	addr)
{
	register db_breakpoint_t	bkpt;

	bkpt = db_breakpoint_alloc();
	if (bkpt == 0) {
	    db_printf("Too many breakpoints.\n");
	    return 0;
	}
	bkpt->task = task;
	bkpt->address = addr;
	bkpt->flags = BKPT_TEMP;
	bkpt->threads = 0;
	if (db_add_thread_breakpoint(bkpt, 0, 1, FALSE) < 0) {
	    if (bkpt)
		db_breakpoint_free(bkpt);
	    db_printf("Too many thread_breakpoints.\n");
	    return 0;
	}
	bkpt->bkpt_inst = db_get_task_value(bkpt->address, BKPT_SIZE, 
						FALSE, task);
	db_put_task_value(bkpt->address, BKPT_SIZE, 
				BKPT_SET(bkpt->bkpt_inst), task);
	return bkpt;
}
Example #3
0
void
db_set_breakpoint(
	task_t		task,
	db_addr_t	addr,
	int		count,
	thread_act_t	thr_act,
	boolean_t	task_bpt)
{
	register db_breakpoint_t bkpt;
	db_breakpoint_t alloc_bkpt = 0;
	vm_offset_t task_thd;

	bkpt = db_find_breakpoint(task, addr);
	if (bkpt) {
	    if (thr_act == THR_ACT_NULL
		|| db_find_thread_breakpoint(bkpt, thr_act)) {
		db_printf("Already set.\n");
		return;
	    }
	} else {
	    if (!DB_CHECK_ACCESS(addr, BKPT_SIZE, task)) {
		if (task) {
		    db_printf("Warning: non-resident page for breakpoint at %lX",
			      addr);
		    db_printf(" in task %lX.\n", task);
		} else {
		    db_printf("Cannot set breakpoint at %lX in kernel space.\n",
			      addr);
		    return;
		}
	    }
	    alloc_bkpt = bkpt = db_breakpoint_alloc();
	    if (bkpt == 0) {
		db_printf("Too many breakpoints.\n");
		return;
	    }
	    bkpt->task = task;
	    bkpt->flags = (task && thr_act == THR_ACT_NULL)?
				(BKPT_USR_GLOBAL|BKPT_1ST_SET): 0;
	    bkpt->address = addr;
	    bkpt->threads = 0;
	}
	if (db_breakpoint_list == 0)
	    db_breakpoint_number = 0;
	task_thd = (task_bpt)	? (vm_offset_t)(thr_act->task)
				: (vm_offset_t)thr_act;
	if (db_add_thread_breakpoint(bkpt, task_thd, count, task_bpt) < 0) {
	    if (alloc_bkpt)
		db_breakpoint_free(alloc_bkpt);
	    db_printf("Too many thread_breakpoints.\n");
	} else {
	    db_printf("set breakpoint #%x\n", db_breakpoint_number);
	    if (alloc_bkpt) {
		bkpt->link = db_breakpoint_list;
		db_breakpoint_list = bkpt;
	    }
	}
}
Example #4
0
void
db_delete_temp_breakpoint(
	task_t		task,
	db_breakpoint_t	bkpt)
{
	db_put_task_value(bkpt->address, BKPT_SIZE, bkpt->bkpt_inst, task);
	db_delete_thread_breakpoint(bkpt, 0);
	db_breakpoint_free(bkpt);
}
Example #5
0
void
db_check_breakpoint_valid(void)
{
	register db_thread_breakpoint_t tbp, tbp_next;
	register db_breakpoint_t bkpt, *bkptp;

	bkptp = &db_breakpoint_list;
	for (bkpt = *bkptp; bkpt; bkpt = *bkptp) {
	    if (bkpt->task != TASK_NULL) {
		if (db_lookup_task(bkpt->task) < 0) {
		    db_force_delete_breakpoint(bkpt, 0, FALSE);
		    *bkptp = bkpt->link;
		    db_breakpoint_free(bkpt);
		    continue;
		}
	    } else {
		for (tbp = bkpt->threads; tbp; tbp = tbp_next) {
		    tbp_next = tbp->tb_next;
		    if (tbp->tb_task_thd == 0)
			continue;
		    if ((tbp->tb_is_task && 
			 db_lookup_task((task_t)(tbp->tb_task_thd)) < 0) ||
			(!tbp->tb_is_task && 
			 db_lookup_act((thread_act_t)(tbp->tb_task_thd)) < 0)) {
			db_force_delete_breakpoint(bkpt, 
					tbp->tb_task_thd, tbp->tb_is_task);
		    }
		}
		if (bkpt->threads == 0) {
		    db_put_task_value(bkpt->address, BKPT_SIZE,
				 bkpt->bkpt_inst, bkpt->task);
		    *bkptp = bkpt->link;
		    db_breakpoint_free(bkpt);
		    continue;
		}
	    }
	    bkptp = &bkpt->link;
	}
}
Example #6
0
void
db_clear_breakpoints(void)
{
	register db_breakpoint_t bkpt, *bkptp;
	register task_t	 task;
	db_expr_t inst;
	thread_act_t	 cur_act = current_act();
	task_t	 cur_task = (cur_act && !cur_act->kernel_loaded) ?
			cur_act->task: TASK_NULL;

	if (db_breakpoints_inserted) {
	    bkptp = &db_breakpoint_list;
	    for (bkpt = *bkptp; bkpt; bkpt = *bkptp) {
		task = bkpt->task;
		if (bkpt->flags & BKPT_USR_GLOBAL) {
		    if (cur_task == TASK_NULL) {
			bkptp = &bkpt->link;
			continue;
		    }
		    task = cur_task;
		}
		if ((bkpt->flags & BKPT_SET_IN_MEM)
		    && DB_CHECK_ACCESS(bkpt->address, BKPT_SIZE, task)) {
		    inst = db_get_task_value(bkpt->address, BKPT_SIZE, FALSE, 
								task);
		    if (inst != BKPT_SET(inst)) {
			if (bkpt->flags & BKPT_USR_GLOBAL) {
			    bkptp = &bkpt->link;
			    continue;
			}
			db_force_delete_breakpoint(bkpt, 0, FALSE);
			*bkptp = bkpt->link;
		        db_breakpoint_free(bkpt);
			continue;
		    }
		    db_put_task_value(bkpt->address, BKPT_SIZE,
				 bkpt->bkpt_inst, task);
		    bkpt->flags &= ~BKPT_SET_IN_MEM;
		}
		bkptp = &bkpt->link;
	    }
	    db_breakpoints_inserted = FALSE;
	}
}
Example #7
0
void
db_delete_breakpoint(db_addr_t addr)
{
	db_breakpoint_t	bkpt;
	db_breakpoint_t	*prev;

	for (prev = &db_breakpoint_list; (bkpt = *prev) != 0;
	    prev = &bkpt->link) {
		if (bkpt->address == addr) {
			*prev = bkpt->link;
			break;
		}
	}
	if (bkpt == 0) {
		db_printf("Not set.\n");
		return;
	}

	db_breakpoint_free(bkpt);
}
Example #8
0
void
db_delete_temp_breakpoint(db_breakpoint_t bkpt)
{
	db_put_value(bkpt->address, BKPT_SIZE, bkpt->bkpt_inst);
	db_breakpoint_free(bkpt);
}