Как Linux uprobe обрабатывает точку останова? - PullRequest
1 голос
/ 14 июля 2020

Насколько я понимаю, на 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();
    }
}
...