15

我正在开发一个非常大的应用程序,我想定期记录整个调用堆栈,直到当前执行点(而不是异常)。这里的想法是,我想要一张准确的代码路径图,它引导我到达我现在的位置。我一直在使用 madExcept,使用 jclDebug 进行工具化,虽然我可以获得一些调用堆栈,但我似乎无法让应用程序中进行的每个方法/过程/函数调用都显示在日志中。

我在项目上启用了堆栈帧、调试信息等。我什至尝试在未包含在调用堆栈中的单个方法上打开堆栈帧,但无济于事。

我想要做的甚至可能吗?我真的在努力避免在我们数百万行代码中添加日志代码以记录代码路径。

4

5 回答 5

23

我使用JCL中的 JCLDebug来做到这一点。

以下将获取当前位置的调用堆栈并将其作为字符串返回。

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 中。

我最近在插入到 EXE 中的 JDBG 文件之间切换到只发送外部 JDBG 文件,因为它更易于维护。

还有一些对跟踪有用的例程,例如:

function ProcByLevel(Level : Integer) : String;

这使您可以确定在调用堆栈“N”个级别中回顾的当前方法/过程名称。

于 2010-02-25T19:48:03.007 回答
8

您可以使用madExcept - 它包含一个名为GetThreadStackTrace的方法。MadExcept 可免费用于非商业用途,否则绝对物有所值。

于 2010-02-24T17:37:48.690 回答
7

从回复和评论到其他答案,听起来您需要一个 CALL LOG,而不是 CALL STACK。您想要的信息根本不存在于调用堆栈中。

在这种情况下,我建议您研究诸如SmartInspectAQ Time之类的工具。在这两者中,我认为 SmartInspect 最有可能是相关的。AQ Time 更像是一种交互式分析工具,而 SmartInspect 具有专门用于远程检查的设施。

于 2010-02-24T19:52:00.837 回答
6

当你从一个方法返回时,它会从堆栈中移除。那么大概您的 Partial 调用堆栈是尚未返回的每个方法?

例如

DoSomething
begin
    MiniSubMethod
    DomeSomethingMore
    begin
        InnerDoSomething
        begin
            ShowCallStack
        end
    end
end

我认为在这种情况下调用堆栈将是

InnerDoSomething  
DoSomethingMore  
DoSomething  

MiniSubMethod 不再在堆栈上,因为它在调用 DoSomethingMore 之前返回。

我认为 FastMM4 包含一个堆栈跟踪,因此您可以尝试一下。

您肯定需要某种日志记录/堆栈跟踪,而不仅仅是调用堆栈。

于 2010-02-24T15:30:06.333 回答
1

如果它是您想要的完整跟踪,我相信像SmartInspect这样的工具可以带您走很长的路。

这将要求您将日志记录添加到您的代码中,但对于您的需要,这将是不可避免的。

它的一些亮点

实时监控
通过 TCP 或命名管道到控制台的高性能实时日志记录

监视和监视资源
跟踪变量值、会话数据和其他应用程序资源。

丰富的日志和跟踪
跟踪消息、异常、对象、文件、数据库结果等。

于 2010-02-25T08:01:55.247 回答