Есть ли способ установить точку останова в gdb, которая зависит от стека вызовов?

Утечка памяти : Сбой к свободной памяти, в которой Вы больше не нуждаетесь прежде также:

  • программа завершается
  • , Дополнительная память выделяется

Лучший способ предотвратить Утечки памяти : Свободная память, как только это больше не необходимо.

26
задан phuclv 23 November 2015 в 10:33
поделиться

3 ответа

Обновление: Теперь есть лучший ответ на этот вопрос: используйте вспомогательную функцию GDB _is_caller.

Необходимость, которую вы описываете, возникает довольно часто, обычно в контексте some_utility_fn, когда вам часто звонят, но вас интересует только звонок, который приходит из some_other_fn.

Вероятно, вы могли бы написать сценарий всего этого взаимодействия, используя новую встроенную поддержку Python в GDB из ствола CVS.

Без Python вы ограничены в том, что вы можете сделать, но обычная техника состоит в том, чтобы отключить отключенную точку останова на a() и включить ее с помощью команды, присоединенной к точке останова на b() ].

Вот пример:

int a(int x)
{
  return x + 1;
}

int b()
{
  return a(1);
}

int call_a_lots()
{
  int i, sum = 0;
  for (i = 0; i < 100; i++)
    sum += a(i);
}

int main()
{
  call_a_lots();
  return b();
}

gcc -g t.c
gdb -q ./a.out
Reading symbols from /tmp/a.out...done.
(gdb) break a
Breakpoint 1 at 0x4004cb: file t.c, line 3.
(gdb) disable 1
(gdb) break b
Breakpoint 2 at 0x4004d7: file t.c, line 8.
(gdb) command 2
>silent
>enable 1
>continue
>end
(gdb) run

Breakpoint 1, a (x=1) at t.c:3
3     return x + 1;
(gdb) bt
#0  a (x=1) at t.c:3
#1  0x00000000004004e1 in b () at t.c:8
#2  0x000000000040052c in main () at t.c:21
(gdb) q

Вуаля: мы остановились на a(), вызванном из b(), игнорируя предыдущие 100 вызовов на a().

23
ответ дан 28 November 2019 в 07:24
поделиться

Я проверил это на GDB 7.6, который уже доступен, но он не работает на GDB 7.2 и, вероятно, на GDB 7.1:

Так что это main.cpp:

int a()
{
  int p = 0;
  p = p +1;
  return  p;
}

int b()
{
  return a();
}

int c()
{
  return a();
}

int main()
{
  c();
  b();
  a();
  return 0;
}

Затем g ++ -g main.cpp

Это my_check.py:

class MyBreakpoint (gdb.Breakpoint):
    def stop (self):
        if gdb.selected_frame().older().name()=="b":
          gdb.execute("bt")
          return True
        else:
          return False

MyBreakpoint("a")

И вот как это работает:

4>gdb -q -x my_check.py ./a.out
Reading symbols from /home/a.out...done.
Breakpoint 1 at 0x400540: file main.cpp, line 3.
(gdb) r
Starting program: /home/a.out
#0  a () at main.cpp:3
#1  0x0000000000400559 in b () at main.cpp:10
#2  0x0000000000400574 in main () at main.cpp:21

Breakpoint 1, a () at main.cpp:3
3         int p = 0;
(gdb) c
Continuing.
[Inferior 1 (process 16739) exited normally]
(gdb) quit
8
ответ дан 28 November 2019 в 07:24
поделиться

Более простое решение, чем сценарии Python, использует временную точку останова .

Это выглядит так:

b ParentFunction
command 1
  tb FunctionImInterestedIn
  c
end

Каждый раз, когда вы входите в ParentFunction, вы устанавливаете одноразовую точку останова для функции, которая вам действительно интересна, затем продолжаете работу (предположительно пока вы не достигнете этой точки останова).

Поскольку вы прервитесь ровно один раз на FunctionImInterestedIn, это не сработает, если FunctionImInterestedIn вызывается несколько раз в контексте ParentFunction, и вы хотите прерывать при каждом вызове.

5
ответ дан 28 November 2019 в 07:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: