GDB:“继续”每隔一次吊钩停止工作
我想根据某些条件忽略断点/观察点命中。乍一看,在GDB:“继续”每隔一次吊钩停止工作,gdb,Gdb,我想根据某些条件忽略断点/观察点命中。乍一看,在hook stop内部使用continue似乎是解决方案。看起来GDB在恢复执行后忽略/禁用了钩子,但不知何故重新启用了钩子,然后在命中后再次禁用钩子,依此类推 下面是一个简单的示例,其中包含复制步骤 我们要调试的程序(“1.c”): 运行:rm/tmp/log;gdb-x cmd--args./a.out gdb会议: Breakpoint 1, foo () at 1.c:4 (gdb) i b breakpoint already hit 2
hook stop
内部使用continue
似乎是解决方案。看起来GDB在恢复执行后忽略/禁用了钩子,但不知何故重新启用了钩子,然后在命中后再次禁用钩子,依此类推
下面是一个简单的示例,其中包含复制步骤
我们要调试的程序(“1.c”):
运行:rm/tmp/log;gdb-x cmd--args./a.out
gdb会议:
Breakpoint 1, foo () at 1.c:4
(gdb) i b
breakpoint already hit 2 times
(gdb) c
Continuing.
Breakpoint 1, foo () at 1.c:4
(gdb) i b
breakpoint already hit 4 times
产生的/tmp/log
:
cont
0
1
cont
2
如果我一直按c,它就会这样继续:2 3 cont 4 5 cont。。。i、 钩子继续执行,但仅每隔一次
这是GDB错误吗?
我如何根据一些复杂的条件自动恢复执行(在我最初的问题中,我有一个观察点,但我想忽略我不感兴趣的函数中的点击)编辑:这一部分已经回答了,感谢雇佣俄罗斯人让我走上了正确的道路。几乎就在同一天,另一个人碰巧对同样的事情感到好奇,我发布了我的答案,唯一剩下的魔法就是过滤器本身:在[“foo”,“bar”]
中返回gdb.selected_frame().name()
我的GDB版本是8.3
在发布这篇文章之前,我盯着这个实现看了一会儿,但实际上还没有试着调试它。
infrun.c
中的此代码看起来可疑:
normal_stop (void):
...
TRY
{
execute_cmd_pre_hook (stop_command);
}
CATCH (ex, RETURN_MASK_ALL)
{
exception_fprintf (gdb_stderr, ex,
"Error while running hook_stop:\n");
}
END_CATCH
/* If the stop hook resumes the target, then there's no point in
trying to notify about the previous stop; its context is
gone. Likewise if the command switches thread or inferior --
the observers would print a stop for the wrong
thread/inferior. */
if (stop_context_changed (saved_context))
{
do_cleanups (old_chain);
return 1;
}
“我想根据某些条件忽略断点/观察点命中。”--您知道GDB直接支持条件断点,对吗?嗯,事实上,我没有意识到观察点也可以是有条件的。我试试看。我还学习了“断点命令列表”:
commands
可以用来代替hook stop
来指定为单个观察点执行的一系列命令。“我想根据某些条件忽略断点/观察点点击。”--您知道GDB直接支持条件断点,对吗?嗯,事实上,我没有意识到观察点也可以是有条件的。我试试看。我还学习了“断点命令列表”:命令
可以用来代替钩子停止
来指定要为单个观察点执行的一系列命令。
cont
0
1
cont
2
normal_stop (void):
...
TRY
{
execute_cmd_pre_hook (stop_command);
}
CATCH (ex, RETURN_MASK_ALL)
{
exception_fprintf (gdb_stderr, ex,
"Error while running hook_stop:\n");
}
END_CATCH
/* If the stop hook resumes the target, then there's no point in
trying to notify about the previous stop; its context is
gone. Likewise if the command switches thread or inferior --
the observers would print a stop for the wrong
thread/inferior. */
if (stop_context_changed (saved_context))
{
do_cleanups (old_chain);
return 1;
}