需要一种方法来定期记录调用的每个方法/过程/函数的调用堆栈/堆栈跟踪

发布于 2024-08-22 23:51:40 字数 276 浏览 3 评论 0原文

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

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

我想做的事情可能吗?我真的试图避免在数百万行代码中添加日志代码来记录代码路径。

I'm working on a very large application where periodically I'd like to log the ENTIRE call stack up until the current execution point (not on an exception). The idea here is that I want a map of the exact code path that led me to the point that I am. I have been working with madExcept, tooled around with jclDebug and while I can get some of the call stack, I can't seem to get EVERY method/procedure/function call that is made in the application to show up in the log.

I've got stack frames turned on, debug info, etc enabled on the project. I even tried turning on stack frames on individual methods that weren't getting included in the call stack to no avail.

Is what I'm trying to do even possible? I'm really trying to avoid having to add logging code all over our millions of lines of code in order to log the code path.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

我不咬妳我踢妳 2024-08-29 23:51:40

我使用 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 文件生成)
  • 插入 EXE 的 JBDG 文件。

我最近在插入 EXE 的 JDBG 文件之间切换为仅传送外部 JDBG 文件,因为这样更容易维护。

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

function ProcByLevel(Level : Integer) : String;

这允许您在调用堆栈“N”号中查找当前方法/过程名称级别。

I use JCLDebug from the JCL to do just this.

The following will get the call stack for the current location and return it as a string.

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;

To make this work as expected, you must enable one of supported ways for Debug Information for JCL such as:

  • Turbo Debugger Information
  • JDBG Files (Generated from the MAP Files)
  • JBDG Files Inserted into the EXE.

I recently switched between JDBG files inserted into the EXE to just shipping the external JDBG files as it was easier to maintain.

There are also routines that are useful for tracing such as:

function ProcByLevel(Level : Integer) : String;

This allows you to determine the current method/procedure name looking back in the call stack "N" number of levels.

月亮邮递员 2024-08-29 23:51:40

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

You can use madExcept - it includes a method named GetThreadStackTrace. MadExcept is free for non-commercial use and definitely worth the price otherwise.

仅一夜美梦 2024-08-29 23:51:40

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

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

From the responses and comments to other answers it sounds like you need a CALL LOG, not a CALL STACK. The information you want simply isn't present in a call stack.

In which case I suggest you investigate a tool such as SmartInspect or AQ Time. Of the two I think SmartInspect is most likely to be relevant. AQ Time is more of an interactive profiling tool, where-as SmartInspect has facilities specifically for remote inspection.

安静 2024-08-29 23:51:40

当您从方法返回时,该方法将从堆栈中删除。所以想必您的部分调用堆栈是尚未返回的每个方法?

例如,

DoSomething
begin
    MiniSubMethod
    DomeSomethingMore
    begin
        InnerDoSomething
        begin
            ShowCallStack
        end
    end
end

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

InnerDoSomething  
DoSomethingMore  
DoSomething  

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

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

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

When you return from a method it is removed from the stack. So presumably your Partial call stack is every method that has not yet returned?

e.g.

DoSomething
begin
    MiniSubMethod
    DomeSomethingMore
    begin
        InnerDoSomething
        begin
            ShowCallStack
        end
    end
end

I would think in this situation the call stack would be

InnerDoSomething  
DoSomethingMore  
DoSomething  

MiniSubMethod is no longer on the stack as it returned before DoSomethingMore was called.

I think FastMM4 includes a Stack Trace so you could try that.

You would definitely need some kind of logging/stack trace instead of just the call stack.

秉烛思 2024-08-29 23:51:40

如果您想要完整的跟踪,我相信像 SmartInspect 这样的工具可能会花费您很长时间

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

它的一些亮点

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

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

丰富的日志记录和日志记录追踪
跟踪消息、异常、对象、文件、数据库结果和信息更多。

If it is a complete trace you want, I believe a tool like SmartInspect could take you a long way.

It would require you to add logging to your code but for what you need, that would be unavoidable.

Some of its highlights

Monitor in Real-Time
High-performance live logging via TCP or named-pipes to the Console

Watch and Monitor Resources
Track variable values, session data and other application resources.

Rich Logging & Tracing
Track messages, exceptions, objects, files, database results & more.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文