是否可以在 VB6 中以编程方式检索调用堆栈?

发布于 2024-07-06 13:26:33 字数 111 浏览 11 评论 0原文

当函数中发生错误时,我想知道导致该错误的事件顺序,特别是当从十几个不同的地方调用该函数时。 有没有办法在VB6中检索调用堆栈,或者我必须以困难的方式做到这一点(例如,每个函数和错误处理程序中的日志条目等)?

When an error occurs in a function, I'd like to know the sequence of events that lead up to it, especially when that function is called from a dozen different places. Is there any way to retrieve the call stack in VB6, or do I have to do it the hard way (e.g., log entries in every function and error handler, etc.)?

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

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

发布评论

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

评论(5

九命猫 2024-07-13 13:26:33

您确实必须以困难的方式做到这一点,但这并不是真的那么那么难...说真的,一旦您编写了一次模板,它就可以快速复制/粘贴/修改以使 Err.Raise 语句中的函数名称与实际函数名称相匹配。

Private Function DoSomething(ByVal Arg as String)

    On Error GoTo Handler

    Dim ThisVar as String
    Dim ThatVar as Long

    ' Code here to implement DoSomething...

    Exit Function

Handler:
    Err.Raise Err.Number, , "MiscFunctions.DoSomething: " & Err.Description

End Function

当您有嵌套调用时,当每个例程命中其处理程序并将其名称添加到错误描述时,此过程就会展开。 在顶层函数中,您会得到一个“调用堆栈”,显示所调用的例程列表以及实际发生的错误的错误号和描述。 它并不完美,因为您没有获得行号,但我发现您通常不需要它们来找到解决问题的方法。 (如果您确实想要行号,您可以将它们放入函数中,并使用 Erl 变量在 Err.Raise 语句中引用它们。如果没有行号,则只会返回 0。)

另外,请注意,在函数本身中,您可以可以使用消息中有趣的变量值引发您自己的错误,如下所示:(

Err.Raise PCLOADLETTER_ERRNUM, , "PC Load Letter error on Printer """ & PrinterName & """"

语法突出显示在预览中看起来很奇怪......我想知道发布后它会是什么样子?)

You do have to do it the hard way, but it's not really all that hard... Seriously, once you've written the template once, it's a quick copy/paste/modify to match the function name in the Err.Raise statement to the actual function name.

Private Function DoSomething(ByVal Arg as String)

    On Error GoTo Handler

    Dim ThisVar as String
    Dim ThatVar as Long

    ' Code here to implement DoSomething...

    Exit Function

Handler:
    Err.Raise Err.Number, , "MiscFunctions.DoSomething: " & Err.Description

End Function

When you have nested calls, this unwinds as each routine hits its Handler and adds its name to the error description. At the top level function, you get a "call stack" showing the list of routines that were called, and the error number and description of the error that actually occurred. It's not perfect, in that you don't get line numbers, but I've found that you don't usually need them to find your way to the problem. (And if you really want line numbers, you can put them in the function and reference them in the Err.Raise statement using the Erl variable. Without line numbers, that just returns 0.)

Also, note that within the function itself, you can raise your own errors with the values of interesting variables in the message like so:

Err.Raise PCLOADLETTER_ERRNUM, , "PC Load Letter error on Printer """ & PrinterName & """"

(The syntax highlighting looks wonky in the preview... I wonder how will it look when posted?)

世俗缘 2024-07-13 13:26:33

我很确定你必须以艰难的方式做到这一点。 在我之前的工作中,我们为带有 DCOM 组件的 VB6 提供了一个非常优雅的错误处理过程。 然而,必须将大量冗余代码添加到每个方法中,以至于我们有自己开发的工具来为您插入所有代码。

我无法提供太多关于其实施的见解(因为我已经忘记了大部分内容,而且他们有可能将其视为商业秘密)。 值得注意的一件事是,方法名称无法在运行时派生,因此它被添加为字符串变量(一些开发人员会复制粘贴而不是使用该工具,这会导致错误堆栈。 ..)。

华泰

I'm pretty sure you have to do it the hard way. At a previous job of mine, we had a very elegant error handling process for VB6 with DCOM components. However, it was a lot redundant code that had to be added to every method, so much that we had home-grown tools to insert it all for you.

I can't provide too much insight on its implementation (both because I've forgotten most of it and there's a chance they may consider it a trade secret). One thing that does stand out was that the method name couldn't be derived at run-time so it was added as a string variable (some developers would copy-paste instead of using the tool and it would lead to error stacks that lied...).

HTH

风筝在阴天搁浅。 2024-07-13 13:26:33

困难的手动方法几乎是唯一的方法。 如果您查看这个问题,有人建议使用一个名为 MZTools 的工具,它可以为您完成大部分繁重的工作。

The hard, manual way is pretty much the only way. If you check out this question, someone suggested a tool called MZTools that will do much of the grunt work for you.

撩心不撩汉 2024-07-13 13:26:33

正如其他人所说(几年前,我明白了......但还有很多人仍在使用 VB6!:)),我认为不可能以编程方式检索调用堆栈,除非您使用某些第三方工具。

但是,如果出于调试目的需要这样做,您可以考虑向被调用的例程添加一个可选输入字符串变量,您将输入调用者的姓名。

Sub MyRoutine
    (...)  ' Your code here
    call DoSomething (Var1, Var2, Var3, "MyRoutine")
    '                                       ^
    '     Present routine's name -----------+

    (...)  ' Your code here

End Sub


Public DoSomething (DoVar1, DoVar2, DoVar3, Optional Caller as string = "[unknown]")
    Debug.Print " DoSomething Routine Called. Caller = " & Caller

    ... ' (your code here)

End Sub

也许不是那么优雅,但它对我有用。

问候,
马克斯 - 意大利

As other people said (years ago, I see... but there's so many people still using VB6! :) ), I think it's not possible to programmatically retrieve the Call Stack, unless you use some 3rd-party tool.

But if you need to do that for debugging purposes, you can consider of adding to the called routine an Optional input string variable, were you'll put the caller's name.

Sub MyRoutine
    (...)  ' Your code here
    call DoSomething (Var1, Var2, Var3, "MyRoutine")
    '                                       ^
    '     Present routine's name -----------+

    (...)  ' Your code here

End Sub


Public DoSomething (DoVar1, DoVar2, DoVar3, Optional Caller as string = "[unknown]")
    Debug.Print " DoSomething Routine Called. Caller = " & Caller

    ... ' (your code here)

End Sub

Not so elegant, maybe, but it worked for me.

Regards,
Max - Italy

我的鱼塘能养鲲 2024-07-13 13:26:33

Compuware(或者当时的 Numega)DevStudio for Visual Basic 6 曾用于执行此操作。 方法是向每个调用添加添加仪器,调用添加到代码堆栈的非常小的片段。 出现任何错误时,它都会转储该调用堆栈,然后执行诸如邮件或将所有调试信息发布到网络服务器之类的操作。 添加和删​​除仪器是一个潜在致命的操作(特别是在当时,当我们使用 VSS 作为源代码控制时),但如果它有效,它就可以很好地工作。

正如 Darrel 指出的 ,您可以通过使用 MZTools 并设置模板来添加非常相似的内容。 这是一项繁重的工作,并且可能比奖励更多的努力,但如果你很难追踪错误,它可能会有所帮助)。

Compuware (or was it Numega at the time) DevStudio for Visual Basic 6 used to do this. The way was by adding adding instrumenation to every call that called a very small snippet that added to the code stack. On any error it dumped out that callstack, and then did things like mail or post to a webserver all the debuging information. Adding and removing the instrumentation was a potentially lethal operation (especially back then, when we were using VSS as our source control), but if it worked, it work well.

As Darrel pointed out, you could add something very simlar by using MZTools and setting up a template. It's a lot of working, and is probably more effeort than the reward would be but if you have very difficult to track down bugs, it might help).

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