Нужен способ периодически регистрировать стек вызовов / трассировку стека для КАЖДОГО вызываемого метода / процедуры / функции - PullRequest
12 голосов
/ 24 февраля 2010

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

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

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

Ответы [ 5 ]

23 голосов
/ 25 февраля 2010

Я использую 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 Debugger Information
  • Файлы JDBG (сгенерированные из файлов MAP)
  • Файлы JBDG, вставленные в EXE.

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

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

function ProcByLevel(Level : Integer) : String;

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

7 голосов
/ 24 февраля 2010

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

7 голосов
/ 24 февраля 2010

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

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

6 голосов
/ 24 февраля 2010

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

, например

DoSomething
begin
    MiniSubMethod
    DomeSomethingMore
    begin
        InnerDoSomething
        begin
            ShowCallStack
        end
    end
end

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

InnerDoSomething  
DoSomethingMore  
DoSomething  

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

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

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

1 голос
/ 25 февраля 2010

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

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

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

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

Rich Logging & Tracing
Отслеживание сообщений, исключений, объектов, файлов, результатов базы данных и т. Д.

...