【发布时间】:2010-05-09 06:27:42
【问题描述】:
VB6 应用程序在多个地方遇到运行时错误。
我知道这是错误处理不当造成的,但是否可以分析代码以查看哪些地方容易受到运行时错误的影响?
【问题讨论】:
标签: error-handling vb6 runtime-error
VB6 应用程序在多个地方遇到运行时错误。
我知道这是错误处理不当造成的,但是否可以分析代码以查看哪些地方容易受到运行时错误的影响?
【问题讨论】:
标签: error-handling vb6 runtime-error
任何应用程序都容易受到运行时错误的影响,因为对外部资源的调用没有错误处理,因此您可以将这些点确定为开始。
我使用了一个免费工具(很多年前),它可以将错误处理改进为 VB6 代码,它至少会记录错误及其发生的时间点。
【讨论】:
您需要确保代码库中的每个方法(函数、子函数、属性...)都有错误处理语句。可能不是每一个都可以生成运行时错误,但这将保护应用程序在没有大量前期分析的情况下不会崩溃。
确保在任何可执行代码行之前有一个带有标签的语句“On Error GoTo...”,然后确保将该标签和一些错误处理代码放在方法的底部。我使用了一个名为MZ-Tools 3.0 的免费工具,它允许您自动包含此文本。选项中有一个错误处理程序选项卡,可用于指定要放入的文本和位置。这是我的样子:
On Error GoTo l{PROCEDURE_NAME}_Error
{PROCEDURE_BODY}
Exit {PROCEDURE_TYPE}
l{PROCEDURE_NAME}_Error:
LogError "{MODULE_NAME}", "{PROCEDURE_NAME}", Err, Err.Description
然后我只需确保 LogError 函数存在并将错误写入一个我可以查看的日志文件。
【讨论】:
VB6 应用程序中常见的运行时错误来源包括
因此,除了按照其他人的建议进行操作并分析实际错误的来源之外,您还可以从在代码中查找诸如此类的区域开始,并在它们周围进行适当的错误处理。请记住,通常最好的“错误处理”根本不涉及使用 On Error,而是通过检查这些边界情况来提前防止错误,例如
等等……
【讨论】:
On Error GoTo 的建议和bwarner 提到的常见错误在这里都有一些很好的答案。
但可能会扩大范围并利用内置工具来分析断点、监视表达式等代码,尤其适用于调试运行时错误、本地窗口(在调试中经常被忽略,但非常强大)和调用堆栈.你可以从这里获得很多很棒的信息:Debugging Your Code and Handling Errors
考虑其他可能会有所帮助的事情:
【讨论】:
按照 Ryan 的回答和回应的评论,您没有必须在 每个 例程中进行错误处理,只需在每个 Event 和 Sub Main()(以及 API 回调如果他们还没有)。
API 回调指的是由 Win32API 直接调用的例程,通常使用
AddressOf传递给Declared函数。 (即在您的代码中搜索AddressOf并确保所有作为参数提及的例程都有错误处理程序来捕获错误并且不允许它们尝试冒泡。)
我刚刚注意到这并没有真正回答最初提出的问题(尽管给出了回应 Ryan 回答的评论 是一个很好的第一步):一旦你在每个事件等,您都会捕获所有错误,但您将无法直接分析所有错误发生的位置。您需要将错误记录至少扩展到记录错误的事件调用的所有例程,以便更准确地定位每个错误的确切来源。
【讨论】:
在 VB6 中,运行时错误发生在事件函数在没有错误处理的情况下被调用时。所以至少你所有的事件处理函数(比如 Form.Open())应该被一个错误处理程序包围(是的,我知道 VB6 没有它们),它可以很好地像这样实现(我们在所有应用程序中都这样做)像这样):
将此作为每个事件处理函数的第一行(它是一个大的有效标签,在末尾设置 On Error):
¦¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯: On Error GoTo ErrorHandler:
现在在所有这些函数的末尾使用它:
¦____________________________________________________________________________________________________________________________________: Exit Sub
ErrorHandler: handleError CodeDb, "Form_frm_filter_deletecolum", "cmd_deletecolum_Click", err.Number, err.description, err.Source, err.LastDllError, err.Helpfile, err.HelpContext, Erl: err.Clear
但是用模块名和函数名替换这两个字符串。并将每个 On Error Goto 0 替换为 On Error Goto ErrorHandler。
现在使用给定的参数创建一个函数 handleError(在我的应用程序中,它会自动将错误报告发送到我们的错误跟踪系统),并显示一个很好的错误消息。
我们甚至进一步推动了这一点,通过一个预构建的过程,将类似的行添加到所有其他(意味着非事件函数,或仅由其他函数调用的函数),以记住发生错误的行并累积完整的堆栈跟踪(是的,VB6 中的堆栈跟踪!)。此外,此过程将行号添加到每一行,以便在错误处理程序的 Erl 部分中给出它们。
我们的工具是作为一些 MS Access 模块编写的,所以我不能简单地为您提供它,但您知道您必须去哪里。
【讨论】: