GDB: «продолжить» в крюк-стоп работает каждый раз - PullRequest
0 голосов
/ 26 июня 2019

Я хочу игнорировать попадания в точки останова / наблюдения в зависимости от некоторых условий.На первый взгляд, использование 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 продолжение 4 5 продолжение ... то есть выполнение возобновляется ловушкой, но только через раз.

Это ошибка GDB?

Как мне автоматически возобновить выполнение на основе некоторого сложного условия (в моей исходной задаче у меня есть точка наблюдения, но я хочу игнорировать попадания в функции, которые меня не интересуют)? - Правка: на эту часть уже есть ответ, спасибо Employed Russian за то, что поставил меня на правильный путь.Когда другой человек удивился тому же самому почти в тот же день, я отправил свой ответ там , единственная оставшаяся магическая пустота - это сам фильтр: 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;
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...