问题描述
我试图调试一个通常会导致GDB停止的程序,并在不处于断点时显示SIGTRAP。它发生在加载动态库和其他普通的东西时。在我的断点最终被击中之前,有1000个这样的事件发生,所以我手动继续所有这些不相关的SIGTRAPs是不可行的。但是如果我使用命令处理SIGTRAP nostop noprint
,那么GDB不会停在我的断点处。
似乎必须有一种方法来教育GDB,以便它了解哪种SIGTRAP适合停止,哪些不适合停止。显然GDB知道它是否处于断点处,因为输出非常可靠不同:在断点处,它提到了断点并显示了断点编号 - 但在其他任何SIGTRAP中,它只是表示SIGTRAP。所以我没有打印关于SIGTRAP的消息,而是真的希望GDB自己说:哇,这是一个SIGTRAP,这里没有断点 - 看着我,我即将停止并打印一个无用的SIGTRAP消息,完全破坏了调试会话!我如何静静地继续?请让我知道是否有人有办法做到这一点。 sourceware.org/gdb/current/onlinedocs/gdb/Set-Catchpoints.html#Set-Catchpointsrel =nofollow> catchpoints 来捕获SIGTRAP信号并添加命令来决定是继续还是停止。在此处理程序中,您可以检查,例如信号的原因。
特别感兴趣的是 $ _ siginfo.si_code
,它的值取决于信号交付。 Linux手册页描述了确切的关系。您可以通过编译程序或查看标题来查找这些 SI_USER
, SI_KERNEL
等代码的数值在我的系统上它使用头 /usr/include/bits/siginfo.h
)。我遇到的一些值是:
$ b $ ul
SI_USER
SI_KERNEL
TRAP_TRACE
有了这些信息,以下是一个捕获SIGTRAP并打印原因的示例,然后继续:
捕获信号SIGTRAP
命令
p $ _siginfo.si_code
c
end
#设置另一个断点用于测试
break sleep
现在考虑这个测试然后触发x86上的调试陷阱(-64):
#include< unistd.h>
int main(void){
for(;;){
sleep(5);
asm(int3);
}
返回0;
$ / code>
这个程序会停止 以下是跳过 最后一个音符:SIGTRAP被调试器内部使用,可能上述过多。这在Arch Linux上使用GDB 7.10进行了测试。 I'm trying to debug a program that often causes GDB to stop and display SIGTRAP when it is not at a breakpoint. It happens when loading dynamic libraries and other ordinary stuff. There are like 1,000 of these occurring before my breakpoint is finally hit, so it's non-feasible for me to manually "continue" all these irrelevant SIGTRAPs. But if I use the command It seems like there must be a way to educate GDB so that it understands which SIGTRAP is good for stopping, and which is no good for stopping. Clearly GDB knows whether it is at a breakpoint, because the output is very reliably different: at a breakpoint, it mentions "breakpoint" and shows the breakpoint number--but at any other SIGTRAP, it just says "SIGTRAP". So instead of printing the message about a SIGTRAP, I'd really like GDB to just say to itself, "wow, this is a SIGTRAP and there is no breakpoint here--look at me, I'm about to stop and print a useless SIGTRAP message that completely ruins the debug session! How about I just continue quietly?" Please let me know if someone has a way to do this. You can set catchpoints to catch the SIGTRAP signal and add commands to decide whether to continue or to stop. In this handler, you can inspect convenience variables such as Of particular interest is With this information in hand, here is an example that catches SIGTRAP and prints the reason, then continues: Now consider this test program that sleeps 5 seconds, then triggers a debug trap on x86(-64): This program keeps stopping Here are the final GDB commands that skip the A final note: SIGTRAP is used internally by the debugger, it is possible that the above catches too much. This was tested with GDB 7.10 on Arch Linux. 这篇关于我怎样才能使GDB停止在SIGTRAP只在断点?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! gdb $ c $因为信号被捕获(
si_code
)恰好是0x80,在
),但是再次重复该指令。所以要跳过这条指令,程序计数器( int3
SI_KERNEL $ pc
)必须增加。这样做后,我了解了有关 SIGTRAP
和 si_code
的信息:
SI_KERNEL
)。
TRAP_TRACE
)的SIGTRAP(因为 SIGTRAP
的出发点)。 b $ b int3
指令触发代码为128的SIGTRAP。因此,您需要一些东西来区分指令。
int3
陷阱并仍然保持断点功能的最终GDB命令:
捕获信号SIGTRAP
命令
silent#不打印catchpoint命中
#忽略int3指令(此地址在
#tracepoint使用print $ pc)
if $ pc == 0x400568
set $ pc ++#skip int3
c
end
#忽略TRAP_TRACE即用于断点
,如果$ _siginfo.si_代码== 2
c
结束
结束
handle SIGTRAP nostop noprint
, then GDB will not stop at my breakpoint. $_siginfo
for the reason for the signal.$_siginfo.si_code
, its value depends on the signal that is delivered. The sigaction(2) Linux manual page describes the exact relations. You can find the numeric values for those SI_USER
, SI_KERNEL
, etc. codes by compiling a program or looking in headers (on my system it uses the header /usr/include/bits/siginfo.h
). Some values I have encountered are:SI_USER
SI_KERNEL
TRAP_TRACE
catch signal SIGTRAP
commands
p $_siginfo.si_code
c
end
# Set another breakpoint for testing
break sleep
#include <unistd.h>
int main(void) {
for (;;) {
sleep(5);
asm("int3");
}
return 0;
}
gdb
at the int3
line because the signal is caught (si_code
happens to be 0x80, SI_KERNEL
), but then the instruction is repeated again. So to skip this instruction, the program counter ($pc
) must be incremented. After doing so, I learned this information about SIGTRAP
and si_code
:SI_KERNEL
).TRAP_TRACE
) is received (because of the catchpoint for SIGTRAP
).int3
instruction triggers SIGTRAP with code 128. Thus you needs something to differentiate the instructions.int3
traps and still keep the breakpoints functional:catch signal SIGTRAP
commands
silent # do not print catchpoint hits
# ignore the int3 instruction (this address was looked up at
# the tracepoint using print $pc)
if $pc == 0x400568
set $pc++ # skip int3
c
end
# Ignore TRAP_TRACE that is used for breakpoints
if $_siginfo.si_code == 2
c
end
end