Как получить в gdb лог вызываемых процедур

Вопросы программирования на Free Pascal, использования компилятора и утилит.

Модератор: Модераторы

Как получить в gdb лог вызываемых процедур

Сообщение Сквозняк » 02.10.2020 08:52:56

Нужно посмотреть откуда вызывается процедура во второй или третий вызов и сохранить всё ценное в файл чтобы потом просмотреть
run. Для этого собираю файл с опцией -g Далее
Код: Выделить всё
gdb fyle
backtrace
set logging file mylog.txt
set logging on
run

И в выхлопе почти ничего нет. Как заставить gdb заниматься полезной деятельностью?

Добавлено спустя 1 час 2 минуты 49 секунд:
Вопрос решён при помощи серий writeln в консоль, но всё равно интересно, как gbd с логом может это улучшить.
Сквозняк
энтузиаст
 
Сообщения: 776
Зарегистрирован: 29.06.2006 22:08:32

Re: Как получить в gdb лог вызываемых процедур

Сообщение Seenkao » 02.10.2020 16:48:30

Разве дебаггер должен логи выводить при компилировании?
Я конечно могу ошибаться, но дебаггер как раз для отладки и он ни как на компиляцию проекта не должен влиять. Все логи надо вставлять в саму компилируемую программу. Либо искать способ заставить дебаггер выводить информацию в файл.
Seenkao
новенький
 
Сообщения: 94
Зарегистрирован: 01.04.2020 03:37:12

Re: Как получить в gdb лог вызываемых процедур

Сообщение Сквозняк » 02.10.2020 17:59:43

Нет, это не тот gdb что в IDE встроен, а внешний, что в линукс проинсталлирован. Он не для ошибок при компилировании, а чтобы в уже скомпилированной программе что-то посмотреть. Им можно запустить программу, ввести в консоль команду и он например покажет значение переменной, если её тип есть в СИ. Но для меня это сейчас бесполезно, мне и 10 раз скомпилить не лень чтобы получить эти данные в консоль от самой программы. Весь консольный выхлоп gdb можно направить в файл, как у меня и показано выше. Но там читать вообще нечего, прямо как в анекдоте: в словаре нету слова "вторник" - на букву "Ф" там только флаг и фуфайка.

Ещё есть отладчик valgrind в котором модуль callgrind по слухам умеет показывать дерево выполняемых функций. Если такую информацию выводить в файл, то этим можно ловить повторяющиеся ошибки. Прописать в коде программы повисание в нужном месте, запустить в отладчике а потом читать лог с конца.

Добавлено спустя 3 минуты 35 секунд:
Пишут вот такое, не проверял пока.
Код: Выделить всё
запустите его с помощью Valgrind + Callgrind с помощью этой команды:

valgrind --tool=callgrind ./program

Затем Callgrind создаст файл с именем callgrind.out.1234 (1234 — это идентификатор процесса и, вероятно, будет отличаться при запуске). Откройте этот файл с помощью:

cg_annotate callgrind.out.1234


Добавлено спустя 21 час 15 минут 40 секунд:
valgrind даже выдаёт в лог полезную информацию! Но только после завершения работы работы программы, куда он её складирует до этого и не переполнит-ли хранилище, если поработает подольше, хз. Для компиляции бинаря накопировал опций из двух ИДЕ
Код: Выделить всё
-Sg -CR -Mfpc -Tlinux -Xm -g -gv -gl -ewnhibvq -Sg -Si -Sa -Cr -Ci -Co -CpATHLON64 -OpATHLON64 -XS -p- -b- -Cs4000000 -Ch8000000

Опцию -Tlinux вне линукса использовать не надо :D
В логе можно найти названия процедур буквами, но большая часть обзывается только цифрами. Наверно в бинаре нет их имён или они вызываются извне.
Код: Выделить всё
fn=(50648) SYSUTILS_ENCODETIME$WORD$WORD$WORD$WORD$$TDATETIME
0 255
cfn=(50650)
calls=17 0
0 663
0 153

fn=(50662)
0 176
cfn=(50664)
calls=16 0
0 566
0 336

fn=(50728) SYSTEM_RANDOM$LONGINT$$LONGINT
0 1869
cfn=(50730)
calls=267 0
0 44375
0 1869

В принципе такое хотел получить от gdb, но не судьба.
Сквозняк
энтузиаст
 
Сообщения: 776
Зарегистрирован: 29.06.2006 22:08:32

Re: Как получить в gdb лог вызываемых процедур

Сообщение mig-31 » 06.10.2020 12:15:27

Наверно вся проблема в том, что разработчики огибают gdb для нужд Pascal, а он создан для С. Скорее всего функционал появится, когда допилят дебагер прямо для Pascal.
mig-31
постоялец
 
Сообщения: 221
Зарегистрирован: 14.07.2011 13:46:48

Re: Как получить в gdb лог вызываемых процедур

Сообщение Сквозняк » 06.10.2020 18:01:16

Думаю, что дело не в этом. Про построение дерева функций программы через gdb молчит и яндекс, наверно и для С такого функционала нет. Вальгрин же имитирует ядро линукса, на котором запускается дебажащаяся программа, наверно это нужно для этой задачи. Когда-то писали что будут портировать вальгрин и на винду, но ничего про успех не слышно. Значит имитировать всю хрень разных ядер винды слишком сложно, что-то в винде не то напортачено. А gdb кроссплатформенный и ради линукса в него не станут впихивать ещё 200% кода нерабочего в винде.
Сквозняк
энтузиаст
 
Сообщения: 776
Зарегистрирован: 29.06.2006 22:08:32

Re: Как получить в gdb лог вызываемых процедур

Сообщение zub » 06.10.2020 23:44:27

Посмотрите https://github.com/PascalRiekenberg/LazProfiler в обсуждениях автору предлагалось впилить построение дерева вызовов и экспорт его например в графвиз для визуализации, но вроде так и не реализовано (хотя имхо добавить это не сложно). LazProfiler парсит исходники и вставляет в них свои инструментальные вызовы с помощью fcl-passrc, поэтому на сложных-современных исходниках несработает
zub
долгожитель
 
Сообщения: 2591
Зарегистрирован: 14.11.2005 23:51:26

Re: Как получить в gdb лог вызываемых процедур

Сообщение Сквозняк » 07.10.2020 17:46:54

Если это не сложно, то почему за два года, с момента последнего коммита, никто не заслал такой патч. Для начала экспортировать надо в простой текст, потому что там гигантские объёмы информации. Чуть программа с тормозами поработала и лови несколько мегабайт. Нужно знать что вызвали и кто вызвал, желательно ещё поток и когда. Бывает что процедура выдаёт нехорошие результаты и нужно узнать откуда с кривыми параметрами она вызвалась. Иногда это узнавать можно через отладчик.
Сквозняк
энтузиаст
 
Сообщения: 776
Зарегистрирован: 29.06.2006 22:08:32

Re: Как получить в gdb лог вызываемых процедур

Сообщение zub » 07.10.2020 23:26:39

>Для этого собираю файл с опцией -g Далее
Еще про -O1 забывать не надо, с оптимизацией стек может быть очень странным

>gdb fyle
>backtrace
>set logging file mylog.txt
>set logging on
>run
backtrace показывает стек в текущий момент времени, т.е. после run и остановке на точке останова с помощью backtrace можно посмотреть как вы сюда попали

>>Ещё есть отладчик valgrind в котором модуль callgrind по слухам умеет показывать дерево выполняемых функций
еще к нему есть морда kcachegrind - в ней можно это красивое дерево посмотреть. но valgrind только под линукс(( в винде из аналогичного есть AQTime - но он неумеет fpc, только delphi

>>Наверно вся проблема в том, что разработчики огибают gdb для нужд Pascal, а он создан для С. Скорее всего функционал появится, когда допилят дебагер прямо для Pascal.
проблема в том что для fpc нет качественных профилировщиков

>>Если это не сложно, то почему за два года, с момента последнего коммита, никто не заслал такой патч.
Это действительно не трудно. острой нужды не у кого грамотного не возникало. у тебя возникла, ждем патчи))
Насчет потоков хз, но имена вызывающих процедур там известны даже без стека - в начало всех процедур\функций вставляются их идентифицирующие "префикы" а LazProfiler меряет время между этими префиксами. Добавляй сюда построение дерева вызовов и экспорт этого дерева.
У меня руки сильно чесались, но fcl-passrc на тот момент не мог распарсить мои исходники, соответственно LazProfiler у меня не работал. При следующем обострении тяги к оптимизации попробую добавить.

зы. содержимое стека всегда можно получить используя только силы fpc, без отладчиков и профайлеров:
Код: Выделить всё
...
uses ... lineinfo, ...
...
procedure myDumpAddr(Addr: Pointer;var f:system.text);
begin
  try
    WriteLn(f,BackTraceStrFunc(Addr));
  except
    writeLn(f,SysBackTraceStr(Addr));
  end;
end;


procedure MyDumpExceptionBackTrace(var f:system.text);
var
  FrameCount: integer;
  Frames: PPointer;
  FrameNumber:Integer;
begin
  WriteLn(f,'Stack trace:');
  myDumpAddr(ExceptAddr,f);
  FrameCount:=ExceptFrameCount;
  Frames:=ExceptFrames;
  for FrameNumber := 0 to FrameCount-1 do
    myDumpAddr(Frames[FrameNumber],f);
end;

еще можно AllowReuseOfLineInfoData:=false сделать, кэширование там криво сделано и при попадании в стек чужих адресов следующие свои уже не распознаются
zub
долгожитель
 
Сообщения: 2591
Зарегистрирован: 14.11.2005 23:51:26


Вернуться в Free Pascal Compiler

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 4

Рейтинг@Mail.ru