GDB:钩挂停止中的`continue`每隔一次工作

时间:2019-06-25 22:28:14

标签: gdb

我想根据某些条件忽略断点/观察点命中。乍看之下,在continue中使用hook-stop似乎是解决方案。不过,似乎GDB在恢复执行后会忽略/禁用该挂钩,但随后以某种方式重新启用它,然后在命中时再次禁用它,依此类推。

这是一个具有重现步骤的最小示例。

我们要调试的程序(“ 1.c”):

#include <stdio.h>
FILE *f;
int foo()
{
  static int v = 0;
  fprintf(f, "%d\n", v);
  fflush(f);
  if (v++ == 42)
    return v;
  return foo();
}
int main()
{
  f = fopen("/tmp/log", "a");
  foo();
  return 0;
}

例如gcc -Og -g 1.c

命令文件“ cmd”:

set $cont = 1

def hook-stop
    if ($cont == 1)
       python with open("/tmp/log", "a") as ofile: print("cont", file=ofile)
       continue
    end
end

b foo
r

运行: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 ...即执行通过钩子恢复,但只能每隔一次。

这是GDB错误吗?

如何基于某些复杂条件自动恢复执行(在我最初的问题中,我有一个监视点,但我想忽略不感兴趣的函数中的命中点)? —编辑:这部分已经得到了答复,这要归功于Employed Russian使我走上了正确的道路。当另一个人几乎差不多在同一天想知道同一件事时,我发布了答案there,唯一剩下的魔咒就是过滤器本身:return gdb.selected_frame().name() in ["foo", "bar"]

我的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;
    }

0 个答案:

没有答案