Насколько я понимаю, на x86 uprobe
помещает инструкцию int3
в указанное пользователем место и обрабатывает это исключение при его попадании, что в этом отношении несколько похоже на kprobe
.
Что я не понимаю, так это то, как обработчик выполнения do_int3()
сообщает uprobe
, когда он попадает. Для сравнения, для kprobe
есть вызов kprobe_int3_handler
внутри do_int3
, поэтому мой вопрос: как и где uprobe
регистрирует свои обработчики?
Вот do_int3
из ядра 5.7 на x86:
dotraplinkage void notrace do_int3(struct pt_regs *regs, long error_code)
{
if (poke_int3_handler(regs))
return;
if (!user_mode(regs)) {
rcu_nmi_enter();
preempt_disable();
}
RCU_LOCKDEP_WARN(!rcu_is_watching(), "entry code didn't wake RCU");
#ifdef CONFIG_KGDB_LOW_LEVEL_TRAP
if (kgdb_ll_trap(DIE_INT3, "int3", regs, error_code, X86_TRAP_BP,
SIGTRAP) == NOTIFY_STOP)
goto exit;
#endif /* CONFIG_KGDB_LOW_LEVEL_TRAP */
#ifdef CONFIG_KPROBES
if (kprobe_int3_handler(regs))
goto exit;
#endif
if (notify_die(DIE_INT3, "int3", regs, error_code, X86_TRAP_BP,
SIGTRAP) == NOTIFY_STOP)
goto exit;
cond_local_irq_enable(regs);
do_trap(X86_TRAP_BP, SIGTRAP, "int3", regs, error_code, 0, NULL);
cond_local_irq_disable(regs);
exit:
if (!user_mode(regs)) {
preempt_enable_no_resched();
rcu_nmi_exit();
}
}