是否可以在 VB6 中以编程方式检索调用堆栈?
当函数中发生错误时,我想知道导致该错误的事件顺序,特别是当从十几个不同的地方调用该函数时。 有没有办法在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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您确实必须以困难的方式做到这一点,但这并不是真的那么那么难...说真的,一旦您编写了一次模板,它就可以快速复制/粘贴/修改以使 Err.Raise 语句中的函数名称与实际函数名称相匹配。
当您有嵌套调用时,当每个例程命中其处理程序并将其名称添加到错误描述时,此过程就会展开。 在顶层函数中,您会得到一个“调用堆栈”,显示所调用的例程列表以及实际发生的错误的错误号和描述。 它并不完美,因为您没有获得行号,但我发现您通常不需要它们来找到解决问题的方法。 (如果您确实想要行号,您可以将它们放入函数中,并使用 Erl 变量在 Err.Raise 语句中引用它们。如果没有行号,则只会返回 0。)
另外,请注意,在函数本身中,您可以可以使用消息中有趣的变量值引发您自己的错误,如下所示:(
语法突出显示在预览中看起来很奇怪......我想知道发布后它会是什么样子?)
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.
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:
(The syntax highlighting looks wonky in the preview... I wonder how will it look when posted?)
我很确定你必须以艰难的方式做到这一点。 在我之前的工作中,我们为带有 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
困难的手动方法几乎是唯一的方法。 如果您查看这个问题,有人建议使用一个名为 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.
正如其他人所说(几年前,我明白了......但还有很多人仍在使用 VB6!:)),我认为不可能以编程方式检索调用堆栈,除非您使用某些第三方工具。
但是,如果出于调试目的需要这样做,您可以考虑向被调用的例程添加一个可选输入字符串变量,您将输入调用者的姓名。
也许不是那么优雅,但它对我有用。
问候,
马克斯 - 意大利
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.
Not so elegant, maybe, but it worked for me.
Regards,
Max - Italy
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).