【问题标题】:What is process branch trap?什么是流程分支陷阱?
【发布时间】:2017-08-26 12:14:14
【问题描述】:

首先是一些背景知识:I'm writing a debugger 现在我正在尝试区分不同类型的进程断点。 ptrace()PTRACE_GETSIGINFO请求可以帮助获取tracee信号的详细信息。对于SIGTRAP信号,si_code有几种类型,包括TRAP_BRKPTTRAP_TRACETRAP_BRANCHTRAP_HWBKPT

在Linux中sigaction(man sigaction)的手册中,结构siginfo_t中有一个si_code常量TRAP_BRANCH,手册上说是这个常量表示进程分支陷阱,所以:

1.什么是流程分支陷阱?

我还注意到有一个“TRAP_TRACE”常量,手册上说这个常量表示进程陷阱,所以:

2。进程陷阱和进程分支陷阱有什么区别?

【问题讨论】:

    标签: linux signals ptrace


    【解决方案1】:

    使用源代码

    我喜欢回答您的问题的一种方法是查看来源。你没有说具体是哪个 linux 内核,所以看看 3.17.2 的源代码似乎至少有助于展示这种技术。

    让我们从每个陷阱的递归 grep 开始...

    寻找TRAP_BRANCH

    $ grep -r TRAP_BRANCH .
    ./arch/ia64/kernel/brl_emu.c:       siginfo.si_code = TRAP_BRANCH;
    ./arch/ia64/kernel/traps.c:           case 35: siginfo.si_code = TRAP_BRANCH; ifa = 0; break;
    ./arch/parisc/kernel/traps.c:           handle_gdb_break(regs, TRAP_BRANCH);
    ./include/uapi/asm-generic/siginfo.h:#define TRAP_BRANCH     (__SI_FAULT|3)  /* process taken branch trap */
    

    寻找TRAP_TRACE

    $ grep -r TRAP_TRACE . | egrep -v HV
    ./arch/avr32/kernel/ptrace.c:           code = TRAP_TRACE;
    ./arch/avr32/kernel/ptrace.c:       code = TRAP_TRACE;
    ./arch/blackfin/include/uapi/asm/siginfo.h:#define TRAP_TRACEFLOW   (__SI_FAULT|2)  /* trace buffer overflow ************* */
    ./arch/blackfin/kernel/traps.c:     info.si_code = TRAP_TRACEFLOW;
    ./arch/frv/kernel/traps.c:          (__frame->__status & REG__STATUS_STEPPED) ? TRAP_TRACE : TRAP_BRKPT;
    ./arch/ia64/kernel/brl_emu.c:       siginfo.si_code = TRAP_TRACE;
    ./arch/ia64/kernel/traps.c:           case 36: siginfo.si_code = TRAP_TRACE; ifa = 0; break;
    ./arch/m68k/kernel/asm-offsets.c:   DEFINE(LTRAP_TRACE, TRAP_TRACE);
    ./arch/m68k/kernel/traps.c:     info.si_code = TRAP_TRACE;
    ./arch/m68k/math-emu/fp_entry.S:    pea LTRAP_TRACE
    ./arch/mn10300/kernel/kgdb.c:       si_code = TRAP_TRACE;
    ./arch/mn10300/kernel/traps.c:  [EXCEP_ISTEP >> 3]  = { SIGTRAP,    TRAP_TRACE },   /* Monitor */
    ./arch/openrisc/kernel/traps.c: info.si_code = TRAP_TRACE;
    ./arch/parisc/kernel/ptrace.c:      si.si_code = TRAP_TRACE;
    ./arch/parisc/kernel/traps.c:           handle_gdb_break(regs, TRAP_TRACE);
    ./arch/powerpc/kernel/traps.c:  info->si_code = TRAP_TRACE;
    ./arch/powerpc/kernel/traps.c:  _exception(SIGTRAP, regs, TRAP_TRACE, regs->nip);
    ./arch/powerpc/kernel/traps.c:      _exception(SIGTRAP, regs, TRAP_TRACE, regs->nip);
    ./arch/x86/include/asm/traps.h:#include <asm/siginfo.h>         /* TRAP_TRACE, ... */
    ./arch/x86/include/asm/traps.h:     return TRAP_TRACE;
    ./include/uapi/asm-generic/siginfo.h:#define TRAP_TRACE (__SI_FAULT|2)  /* process trace trap */
    

    比较 grep 结果

    因此,至少相对而言,TRAP_TRACE 似乎比TRAP_BRANCH 更频繁地用于更多架构。更具体地说,TRAP_BRANCH 仅用于 2 个架构(ia64parisc),而TRAP_TRACE 用于 10 个架构(avr32blackfinfrvia64、@98765436 @、mn10300openriscpariscpowerpcx86)。

    但是,我觉得仅仅注意到句法上的差异还不够令人满意。我也想了解语义差异。

    检查代码

    从 grep 输出中,我看到在 ./arch/*/kernel/traps.c 文件中最一致地找到匹配的模式。

    然后看看./arch/parisc/kernel/traps.c,其中使用了两个陷阱,我看到它们都在handle_interruption 函数的上下文中使用。 TRAP_TRACE 是整数 code 的 3,TRAP_BRANCH 是整数 code 的 25。搜索 handle_interruption 的调用,我发现只有 ./arch/parisc/kernel/entry.S 调用了这个函数。

    所以现在我们在硬件领域 (IMO) 陷入困境,是时候从源代码着手了。

    查看技术手册

    pa risc code for TRAP_BRANCH 的快速 google 提供 PA-RISC 1.1 Architecture and Instruction Set ... - PA-RISC Linux 作为热门搜索。

    在此 PDF 中,搜索中断代码 25 会显示手册的 中断 部分,其中显示了两个代码。代码 3 根据优先级出现在中断类别的“组 2”中,其中指定为“恢复计数器陷阱”,而代码 25 出现在“组 4”中并称为“采取分支陷阱”。

    接下来搜索“Taken branch”,我发现 PSW 禁用/启用位的 T 字段以及以下符号:

    已启用分支陷阱。为 1 时,任何已采用的分支都会以已采用的分支陷阱终止。

    然后:

    与分支相关的陷阱

    分支指令可能会根据 PSW 位的值引起各种陷阱。如果 PSW T 位为 1,并且采用分支,则发生采用分支陷阱。此陷阱可用于调试目的。如果 PSW H 位为 1,并且分支指令提升了特权级别,则会发生更高特权转移陷阱。如果 PSW L 位为 1,并且分支指令降低了特权级别,则会发生低特权转移陷阱。

    “恢复计数器”的同时显示:

    恢复计数器

    恢复计数器 (CR 0) 是一个 32 位计数器,可用于在容错系统中提供硬件故障的软件恢复,也可用于调试目的。

    文档后面有一条注释说:

    恢复计数器可用于记录正常操作期间的中断,并模拟故障恢复期间的中断。

    总结

    据我所知(至少对于 PA RISC 架构)...

    1. 进程分支陷阱TRAP_BRANCH linux 代码相关联,可在某些架构上用于检测何时采用代码分支。
    2. “进程陷阱”和“进程分支陷阱”的区别,假设“进程陷阱”是指TRAP_TRACE linux 代码,前者用于调试中断处理,而后者用于调试所采用的分支。

    我怀疑这些答案对于其他架构来说并不算太遥远,但我会将检查其他架构留给其他人去做。

    希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 2011-12-13
      • 2011-02-26
      • 1970-01-01
      • 1970-01-01
      • 2018-08-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-18
      相关资源
      最近更新 更多