什么是流程分支陷阱?

时间:2017-08-26 12:14:15

标签: linux signals ptrace

首先是一些背景:I'm writing a debugger现在我试图区分不同类型的进程断点。 PTRACE_GETSIGINFO的{​​{1}}请求可以帮助检索tracee信号的详细信息。对于ptrace()信号,有SIGTRAP种类型,包括si_codeTRAP_BRKPTTRAP_TRACETRAP_BRANCH

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

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

我还注意到有一个'TRAP_TRACE`常量,手册说这个常量表示过程陷阱,所以:

2。过程陷阱和过程分支陷阱之间有什么区别?

1 个答案:

答案 0 :(得分:2)

使用来源

回答我喜欢的问题的方法是查看来源。你没有具体说明哪个linux内核,所以看看3.17.2来源似乎至少可以用来说明这种技术。

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

Grepping for 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 */

Grepping for 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。更具体地说,ia64仅用于2个体系结构(pariscTRAP_TRACE),而avr32用于10个体系结构(blackfin,{{1} },frvia64m68kmn10300openriscpariscpowerpcx86 )。

我发现它并不足以让人注意到句法上的差异。我也想了解语义差异。

检查代码

从grep输出中,我看到了./arch/*/kernel/traps.c文件中最常见匹配的模式。

然后在./arch/parisc/kernel/traps.c处取一个gander,其中有两个陷阱,我看到这些都在handle_interruption函数的上下文中使用。 TRAP_TRACE表示整数code为3,TRAP_BRANCH表示整数code为25.搜索handle_interruption的调用时,我看到它只来自{{ 1}}调用此函数。

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

查看技术手册

快速谷歌./arch/parisc/kernel/entry.S提供PA-RISC 1.1 Architecture and Instruction Set ... - PA-RISC Linux作为最高点。

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

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

  

采取分支陷阱启用。当为1时,任何采用的分支都被截取的分支陷阱终止。

然后:

  

与分支相关的陷阱

     

分支指令可能会根据PSW位的值导致各种陷阱。如果PSW T位为1,并且采用分支,则发生采用的分支陷阱。此陷阱可用于调试目的。如果PSW H位为1,并且分支指令提高了权限级别,则会发生更高权限的传输陷阱。如果PSW L-bit为1,并且分支指令降低了权限级别,则会发生权限较低的传输陷阱。

与此同时,“恢复计数器”的文字说:

  

恢复计数器

     

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

稍后在文档中有一条说明:

  

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

摘要

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

  1. 进程分支陷阱pa risc code for TRAP_BRANCH linux代码相关联,并且在某些体系结构上可用于检测何时执行代码分支。
  2. “进程陷阱”和“进程分支陷阱”之间的区别,假设“进程陷阱”是指TRAP_BRANCH linux代码,前者用于调试中断处理,而后者用于调试正在进行的分支。
  3. 我怀疑这些答案对于其他架构来说并不太远,但我会将其他架构留给别人去做。

    希望这有帮助。