首先是一些背景:I'm writing a debugger现在我试图区分不同类型的进程断点。 PTRACE_GETSIGINFO
的{{1}}请求可以帮助检索tracee信号的详细信息。对于ptrace()
信号,有SIGTRAP
种类型,包括si_code
,TRAP_BRKPT
,TRAP_TRACE
,TRAP_BRANCH
。
在Linux中的TRAP_HWBKPT
(man sigaction)手册中,结构sigaction
中有一个si_code
常量TRAP_BRANCH
,手册中说这是常量表示进程分支陷阱,所以:
1。什么是流程分支陷阱?
我还注意到有一个'TRAP_TRACE`常量,手册说这个常量表示过程陷阱,所以:
2。过程陷阱和过程分支陷阱之间有什么区别?
答案 0 :(得分:2)
回答我喜欢的问题的方法是查看来源。你没有具体说明哪个linux内核,所以看看3.17.2来源似乎至少可以用来说明这种技术。
让我们从每个陷阱的递归greps开始......
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 */
因此,至少相对而言,TRAP_TRACE
似乎比TRAP_BRANCH
更频繁地使用TRAP_BRANCH
。更具体地说,ia64
仅用于2个体系结构(parisc
和TRAP_TRACE
),而avr32
用于10个体系结构(blackfin
,{{1} },frv
,ia64
,m68k
,mn10300
,openrisc
,parisc
,powerpc
和x86
)。
我发现它并不足以让人注意到句法上的差异。我也想了解语义差异。
从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架构而言)......
pa risc code for TRAP_BRANCH
linux代码相关联,并且在某些体系结构上可用于检测何时执行代码分支。TRAP_BRANCH
linux代码,前者用于调试中断处理,而后者用于调试正在进行的分支。我怀疑这些答案对于其他架构来说并不太远,但我会将其他架构留给别人去做。
希望这有帮助。