Необходимо периодически регистрировать трассировку стека/стека вызовов для КАЖДОГО метода/процедуры/функции, называемой

Я работаю над очень большим приложением, где периодически мне нужно записывать полный стек вызовов до текущей точки выполнения (не для исключения). Идея здесь в том, что я хочу, чтобы карта точного кодового пути привела меня к тому, что я есть. Я работал с madExcept, с инструментами jclDebug, и хотя я могу получить часть стека вызовов, я не могу получить КАЖДЫЙ вызов метода/процедуры/функции, который создается в приложении, чтобы отображаться в журнале.

У меня есть фреймы стека, информация об отладке и т.д. включены в проект. Я даже пытался включить фреймы стека по отдельным методам, которые не включались в стек вызовов, но безрезультатно.

Я пытаюсь сделать то, что я пытаюсь сделать? Я действительно стараюсь не добавлять код ведения журнала по всем миллионам строк кода для регистрации пути кода.

Ответ 1

Когда вы возвращаетесь из метода, он удаляется из стека. Итак, предположительно ваш стек частичных вызовов - это все методы, которые еще не вернулись?

например.

DoSomething
begin
    MiniSubMethod
    DomeSomethingMore
    begin
        InnerDoSomething
        begin
            ShowCallStack
        end
    end
end

Я бы подумал, что в этой ситуации стек вызовов будет

InnerDoSomething  
DoSomethingMore  
DoSomething  

MiniSubMethod больше не находится в стеке, поскольку он возвращался до вызова DoSomethingMore.

Я думаю, что FastMM4 включает в себя трассировку стека, чтобы вы могли попробовать это.

Вам определенно понадобится какая-то трассировка журнала/стека, а не только стек вызовов.

Ответ 2

Я использую JCLDebug из JCL, чтобы сделать это.

Следующее получит стек вызовов для текущего местоположения и вернет его как строку.

function GetCurrentStack: string;
var
   stackList: TJclStackInfoList; //JclDebug.pas
   sl: TStringList;
begin
   stackList := JclCreateStackList(False, 0, Caller(0, False));
   sl := TStringList.Create;
   stackList.AddToStrings(sl, True, True, True, True);
   Result := sl.Text;
   sl.Free;
   stacklist.Free; 
end;

Чтобы сделать эту работу ожидаемой, вы должны включить один из поддерживаемых способов для отладочной информации для JCL, например:

  • Информация об отладчике Turbo
  • Файлы JDBG (созданные из файлов MAP)
  • Файлы JBDG, вставленные в EXE.

Недавно я переключился между файлами JDBG, вставленными в EXE, только для отправки внешних файлов JDBG, поскольку их было легче поддерживать.

Существуют также процедуры, которые полезны для отслеживания, такие как:

function ProcByLevel(Level : Integer) : String;

Это позволяет вам определить текущее имя метода/процедуры, оглядываясь на количество уровней стека вызовов "N".

Ответ 3

Из ответов и комментариев к другим ответам кажется, что вам нужен CALL LOG, а не CALL STACK. Информация, которую вы хотите просто, отсутствует в стеке вызовов.

В этом случае я предлагаю вам изучить такой инструмент, как SmartInspect или Время AQ. Из двух я думаю, что SmartInspect, скорее всего, будет иметь значение. AQ Time - это скорее инструмент интерактивного профилирования, где, поскольку SmartInspect имеет возможности специально для удаленного контроля.

Ответ 4

Вы можете использовать madExcept - он включает метод GetThreadStackTrace. MadExcept бесплатно для некоммерческого использования и определенно стоит цена в противном случае.

Ответ 5

Если вам нужна полная трассировка, я считаю, что такой инструмент, как SmartInspect, может пройти долгий путь.

Это потребует от вас добавления журнала в ваш код, но для того, что вам нужно, это было бы неизбежным.

Некоторые из его основных моментов

Монитор в режиме реального времени
Высокопроизводительная запись в реальном времени через TCP или именованные каналы на консоль

Ресурсы наблюдения и мониторинга
Отслеживать значения переменных, данные сеанса и другие ресурсы приложения.

Богатый журнал и трассировка
Отслеживать сообщения, исключения, объекты, файлы, результаты базы данных и т.д.