LINUX.ORG.RU

Как заставить GDB построить трассу программы ?


0

0

Имеется программа на Си. Например 

fact(int x) {

 int f = 1;

 while ( x > 1) {
   f = f * x;
   x = x - 1;
  }  

  return f;
}

main() {
   return fact(3);
}

Хотелось бы для заранее выбранных функций построить трассу их 
выполнения, содержащую все срабатывания операторов присваивания. Например, для функции fact(x) хотелось бы иметь что-то вроде

fact(x), при x = 3 : 
f = 1
f = f * x
x = x - 1
f = f * x
x = x - 1

Полагаю, что такое удобно сделать средствами GDB. Только в GDB я особо не разбираюсь. В какую сторону копать ? 
★★

gcc -ggdb -Wall -O0 fact.c -o fact
gdb fact
>br LINE <- например номер строки с f = f * x
>run
останавливаемся на LINE
>while 1==1
print x
print f
continue
end
печатаем x и f до упора

fghj ★★★★★
()
Ответ на: комментарий от fghj

Не совсем то что нужно. Предложенный скрипт, как я понял, выполняет программу по шагам и печатает значения f и x до тех пор, пока таковые имеются на стеке. Мне нужно несколько другое - надо получить трассу программы состоящую только из операторов присваивания( ну и вариантов вроде ++, --, +=, -= и т.д.) Значения переменных при этом неинтересны. Важен только факт срабатывания оператора. Основная сложность задачи состоит в том, что при пошаговой отладке gdb печатает все выполненные операторы в одну кучу - операторы присваивания, условные операторы, вызовы функций и т.д. Причем иногда один оператор "содержит" в себе несколько других. Например, в for(int i =0; i< 10; ++i) содержатся два оператора присваивания. При этом i=0 выполняется перед первой итерацией цикла, а i++ после каждой итерации. Надо среди всего этого бардака отловить только срабатывания операторов присваивания. Нельзя ли как-нибудь настроить gdb чтобы он при пошаговой отладке выводил только выполненные операторы присваивания.

Burbaka ★★
() автор топика


Ну вот не с помощью gdb, а с помощью dbx:

$cc -g tr.c

$dbx ./a.out
For information about new features see `help changes'
To remove this message, put `dbxenv suppress_startup_message 7.7' in your .dbxrc
Reading a.out
Reading ld.so.1
Reading libc.so.1
(dbx) trace next -in fact
(2) trace next -in fact
(dbx) run | grep =
trace: 3 int f = 1;
trace: 6 f = f * x;
trace: 7 x = x - 1;
trace: 6 f = f * x;
trace: 7 x = x - 1;

dbx брать тут:

http://developers.sun.com/sunstudio/downloads/express/

anonymous
()
Ответ на: комментарий от anonymous

grep = - не учитывает все возможные варианты. Если уж фильтровать операторы ручками, то тут нужен полноценный синтаксический анализ выражений. Ибо выбирать операторы присваивания из строчки кода, которую выводит отладчик, не всегда так просто.

Burbaka ★★
() автор топика

использовать перегрузку операторов. Либо переписать на плюсах, либо заменить все операторы присваивания на что-то типа

OxiD ★★★★
()
Ответ на: комментарий от OxiD

int assign (int *a, int b,char *name)
{
*a=b;
printf("variable %s = %d\n",name,b);
return b;
}

Можно еще как-нибудь с помощью макросов поизвращаться..

OxiD ★★★★
()

Возьми программу на лиспе. Там подобные трейсы искаропки :)

// planed

anonymous
()
Ответ на: комментарий от anonymous

>а с помощью dbx:

За пинок в нужную сторону - респект

anonymous
()

это делается средствами самого gcc - нужно сделать дамп GIMPLE-представления

anonymous
()
Ответ на: комментарий от Burbaka

поставить watchpoint в gdb на переменные и ждать срабатывания? правда с локальными переменными внутри функций не понятно.

или может help tracepoint поможет.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.