Списък на всички извиквания на функции, направени в приложение

Как можем да изброим всички функции, които се извикват в приложение. Опитах да използвам GDB, но списъкът му с обратно проследяване само до извикването на основната функция.

Имам нужда от по-задълбочен списък, т.е. списък на всички функции, които се извикват от основната функция и функцията, която се извиква от тези извикани функции и т.н.

Има ли начин да получите това в gdb? Или можете да ми дадете предложения как да получа това?


person broun    schedule 03.03.2012    source източник
comment
С произволен инструмент: stackoverflow.com/questions/311840/   -  person Ciro Santilli 新疆再教育营六四事件ۍ    schedule 31.07.2015
comment
Възможен дубликат на Make GDB print control flow of functions както се наричат   -  person jww    schedule 31.07.2016
comment
balau82.wordpress.com/2010 /10/06/   -  person Craig Hicks    schedule 30.09.2017


Отговори (4)


Как можем да изброим всички функции, които се извикват в приложение

За всяко приложение с реалистичен размер този списък ще има хиляди записи, което вероятно ще го направи безполезен.

Можете да намерите всички функции, дефинирани (но не непременно извикани) в приложение с командата nm, напр.

nm /path/to/a.out | egrep ' [TW] '

Можете също да използвате GDB, за да зададете точка на прекъсване на всяка функция:

(gdb) set logging on     # collect trace in gdb.txt
(gdb) set confirm off    # you wouldn't want to confirm every one of them
(gdb) rbreak .           # set a breakpoint on each function

След като продължите, ще достигнете точка на прекъсване за всяка извикана функция. Използвайте командите disable и continue, за да продължите напред. Не вярвам, че има лесен начин за автоматизиране на това, освен ако не искате да използвате Python скриптове.

Вече споменатият gprof е друг добър вариант.

person Employed Russian    schedule 03.03.2012
comment
Забележка: това също ще прекъсне кода, който се изпълнява преди _start: stackoverflow.com/questions/31379422/ - person Ciro Santilli 新疆再教育营六四事件ۍ 14.07.2015
comment
gdb седи на 100% процесор, откакто въведох командата rbreak . - person Michael Fox; 31.07.2015
comment
без регистриране, set height 0 ще бъде полезно (без страниране за изход) - person phil294; 13.07.2017
comment
Можете да опитате rbreak ^s[^@]*$, ако искате да зададете точки на прекъсване само за несистемни функции, т.е. да изключите malloc, strlen и други. - person Johannes; 14.02.2019
comment
@Johannes Мисля, че трябва да премахнете това s след ^ - всичко, което получих, бяха несистемни функции, които започват в s... - person Thomas Guyot-Sionnest; 20.09.2020

Искате графика на обажданията. Инструментът, който искате да използвате, не е gdb, а gprof. Компилирате вашата програма с -pg и след това я стартирате. Когато се изпълнява, ще се създаде файл gmon.out. След това обработвате този файл с gprof и се наслаждавате на резултата.

person vy32    schedule 03.03.2012
comment
Съмнявам се, че gprof ви дава последователността от всички извиквания на функции. - person einpoklum; 03.07.2021
comment
Не е завършен, но е доста добър. Вижте ftp.gnu.org/old- gnu/Manuals/gprof-2.9.1/html_chapter/ и docs.oracle.com/cd/E19059-01/wrkshp50/805-4947/6j4m8jrn7/ - person vy32; 04.07.2021
comment
Така че, не, нито е пълно, нито е близо. Връзката, която дадохте, показва, че това е един ред на стек от функции, а не на извикване на функция или стек от функции. Това не е това, което ми трябва. Ако от main, извиквам a(), след това b(), след това a(), след това b() и т.н. - искам да получа main a b a b a b a b и т.н. - person einpoklum; 04.07.2021
comment
Имате предвид, че искате всяко извикване на функция, което вашата програма прави? Искате ли само вашите функции или всички библиотечни функции, всички поддържащи функции на компилатора и т.н. И каква е вашата дефиниция за извикване на функция? - person vy32; 06.07.2021
comment
Всяко обаждане, последователно. - person einpoklum; 06.07.2021
comment
Най-добрият ви залог е да инструментирате компилатора или да модифицирате междинния код или асемблера. Възможно е това да се случи с gprof. - person vy32; 07.07.2021

запис на хронологията на обажданията на функция

https://sourceware.org/gdb/onlinedocs/gdb/Process-Record-and-Replay.html

Това би трябвало да е чудесна възможност за хардуерно ускорение, ако сте един от малкото хора (2015) с процесор, който поддържа Intel Processor Tracing (Intel PT, intel_pt в /proc/cpuinfo).

Документите на GDB твърдят, че може да генерира изход като:

(gdb) list 1, 10
1   void foo (void)
2   {
3   }
4
5   void bar (void)
6   {
7     ...
8     foo ();
9     ...
10  }
(gdb) record function-call-history /ilc
1  bar     inst 1,4     at foo.c:6,8
2    foo   inst 5,10    at foo.c:2,3
3  bar     inst 11,13   at foo.c:9,10

Преди да го използвате, трябва да стартирате:

start
record btrace

което е мястото, където неспособен процесор се проваля с:

 Target does not support branch tracing.

Поддръжката на процесора се обсъжда допълнително на: Как за стартиране на запис на хронология на инструкции и история на извикване на функция в GDB?

Свързани теми:

За вградени обмисляте също JTAG и поддържащ хардуер като DSTREAM, но поддръжката на x86 не изглежда много добра: отстраняване на грешки x86 ядро ​​с помощта на хардуерен дебъгер

person Ciro Santilli 新疆再教育营六四事件ۍ    schedule 04.08.2015

Този въпрос може да се нуждае от пояснение, за да решите между това, което в момента са 2 отговора. Зависи от какво имате нужда:

1) Трябва да знаете колко пъти се извиква всяка функция в прав списък/графичен формат на функции, съпоставени с # извиквания. Това може да доведе до двусмислени/неубедителни резултати, ако вашият код не е процедурен (т.е. функции, извикващи други функции в разклонена структура без неяснота какво извиква какво). Това е основна функционалност на gprof, която изисква повторно компилиране с -pg флаг.

2) Имате нужда от списък с функции в реда, в който са били извикани, това зависи от вашата програма коя е най-добрата/осъществима опция: a) АКО вашата програма се изпълнява и прекратява без грешки по време на изпълнение, можете да използвате gprof за тази цел. b) Опцията ELSE по-горе, използвайки dbg с точки за регистриране и прекъсване, е останалата опция, която научих, след като прочетох това.

3) Трябва да знаете не само реда, но, например, и аргументите на функцията за всяко повикване. Текущата ми работа е симулации във физиката на транспорта на частици, така че това АБСОЛЮТНО би било полезно за проследяване откъде идват аномалните резултати... т.е. когато аргументите, които се предават, спрат да имат смисъл. Предполагам, че един от начините да направите това е вариант на това, което е направил Employed Russian, с изключение на използването на следното:

(gdb) информационни аргументи

Регистрирането на резултатите от тази команда с всяка точка на прекъсване (зададена при всяко извикване на функция) дава аргументите на текущата функция.

person opetrenko    schedule 02.09.2013