Нужен способ периодически регистрировать стек вызовов / трассировку стека для каждого вызываемого метода / процедуры / функции

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

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

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

5 ответов


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

например

DoSomething
begin
    MiniSubMethod
    DomeSomethingMore
    begin
        InnerDoSomething
        begin
            ShowCallStack
        end
    end
end

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

InnerDoSomething  
DoSomethingMore  
DoSomething  

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

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

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


Я использую 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 файлы (генерируемые из файлов карты)
  • файлы JBDG, вставленные в ИСПОЛНЯЕМЫЙ.

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

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

function ProcByLevel(Level : Integer) : String;

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


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

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


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


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

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

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

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

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

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