问题说明了一切。如果您有一个由多个用户报告的错误,但是在日志中没有记录该错误的记录,也无法重复该错误,无论您如何努力,如何解决它?甚至可以吗?
我相信这已经发生在你们当中的许多人身上。在这种情况下,您做了什么?最终结果是什么?
编辑:我更感兴趣的是做关于unfindable的bug,而不是一个无法解决的错误。无法解决的错误使您至少知道存在问题,并且在大多数情况下有一个搜索起点。如果情况不佳,该怎么办?你什至可以做什么?
问题说明了一切。如果您有一个由多个用户报告的错误,但是在日志中没有记录该错误的记录,也无法重复该错误,无论您如何努力,如何解决它?甚至可以吗?
我相信这已经发生在你们当中的许多人身上。在这种情况下,您做了什么?最终结果是什么?
编辑:我更感兴趣的是做关于unfindable的bug,而不是一个无法解决的错误。无法解决的错误使您至少知道存在问题,并且在大多数情况下有一个搜索起点。如果情况不佳,该怎么办?你什至可以做什么?
Answers:
不同的编程语言将具有自己的错误样式。
添加调试语句可以使问题无法被复制,因为调试语句本身移动指针远远不够,以避免段错误---又称Heisenbugs。指针问题很难跟踪和复制,但是调试器可以提供帮助(例如GDB和DDD)。
具有多个线程的应用程序可能仅以非常特定的时序或事件序列显示其错误。不适当的并发实现可能在难以复制的情况下导致死锁。
一些Web浏览器因内存泄漏而臭名昭著。在一个浏览器中运行良好的JavaScript代码可能会在另一浏览器中导致不正确的行为。使用经过成千上万的用户严格测试的第三方库,对于避免某些难以理解的错误可能是有利的。
根据运行该应用程序(具有错误)的环境的复杂性,唯一的办法可能是简化环境。应用程序是否运行:
应用程序在什么环境下会产生问题?
退出无关的应用程序,终止后台任务,停止所有计划的事件(定时作业),消除插件,并卸载浏览器加载项。
由于联网对于许多应用程序都是必不可少的:
消除尽可能多的未知数:
消除生产,测试和开发之间的所有差异。使用相同的硬件。完全按照完全相同的步骤安装计算机。一致性是关键。
使用大量的日志记录来关联事件发生的时间。检查日志中是否有任何明显的错误,计时问题等。
如果软件看起来还可以,请考虑硬件故障:
主要用于嵌入式:
当您在本地运行该应用程序(即不在整个网络中)时会发生什么?其他服务器是否遇到相同的问题?数据库是远程的吗?可以使用本地数据库吗?
硬件和软件之间是固件。
时间问题很难跟踪:
收集有关该问题的硬数字数据。一开始可能是随机出现的问题,实际上可能有一个模式。
有时,系统升级后会出现问题。
不同的操作系统具有不同的分发冲突库的方式:
重新安装操作系统,并仅包括应用程序所需的支持软件。
确保每个库仅使用一次。有时,应用程序容器的库版本与应用程序本身不同。这可能无法在开发环境中复制。
编写检测方法,以在错误发生时触发通知(例如,日志,电子邮件,弹出窗口,寻呼机蜂鸣声)。使用自动测试将数据提交到应用程序中。使用随机数据。使用涵盖已知和可能的极端情况的数据。最终,该错误应重新出现。
值得重申的是其他人提到的:睡在上面。花点时间解决问题,完成其他任务(例如文档)。与计算机保持距离并进行一些运动。
逐行浏览代码,并描述每一行对您自己,同事或橡皮鸭的所作所为。这可能会导致有关如何重现该错误的见解。
宇宙射线可以翻转位。由于内存的现代错误检查,这已不再像过去那样大。由于宇宙辐射的随机性,离开地球保护的硬件软件存在一些根本无法复制的问题。
有时(尽管很少),编译器会引入一个错误,尤其是针对小众工具(例如,遭受符号表溢出的C微控制器编译器)的错误。是否可以使用其他编译器?工具链中的任何其他工具都会引入问题吗?
如果它是一个GUI应用程序,那么观看客户产生错误(或尝试这样做)是非常宝贵的。他们无疑会在做您从未想过的事情(没错,只是有所不同)。
否则,将您的日志集中在该区域。记录所有内容(您可以稍后将其取出),并使您的应用程序也转储其环境。例如,机器类型,VM类型,使用的编码。
您的应用是否报告版本号,内部版本号等?您需要使用它来精确确定要调试的版本(或不!)。
如果您可以检测您的应用程序(例如,如果您在Java世界中,则使用JMX),然后检测相关区域。存储统计信息,例如请求+参数,时间等。利用缓冲区存储最后的'n'个请求/响应/对象版本/所有内容,并在用户报告问题时将其转储出去。
如果您无法复制它,则可以对其进行修复,但不知道已对其进行了修复。
我已经就如何触发该错误做出了最好的解释(即使我不知道这种情况如何发生),也对此进行了修复,并确保如果该错误再次出现,我们的通知机制将使将来的开发人员知道我希望知道的事情。实际上,这意味着在跨越可能触发该错误的路径并记录相关资源的度量时,添加日志事件。并且,当然,要确保测试总体上很好地执行了代码。
确定添加哪些通知是一个可行性和分类问题。因此,首先要确定开发人员要花多少时间在bug上。不知道该错误的重要性是无法回答的。
我有很好的结果(没有再次出现,代码对此也更好),也有不好的结果(花了太多时间不解决问题,不管错误是否最终得以解决)。这就是估计和问题优先级的目的。
这可能很困难,有时几乎是不可能的。但是我的经验是,如果您花了足够的时间(或花费的时间是值得的,那是另一回事),您迟早将能够重现并修复该错误。
在这种情况下可能会有帮助的一般建议。
您无法复制两种错误。您发现的种类以及其他人发现的种类。
如果发现该错误,则应该能够复制它。如果您无法复制它,那么您根本就不会考虑导致该错误的所有因素。这就是为什么每当有错误时都应记录下来。保存日志,获取屏幕截图,等等。如果您不这样做,那么如何证明错误确实存在?也许只是一个错误的记忆?
如果其他人发现了错误,并且您无法复制它,则显然要求他们复制它。如果他们无法复制它,那么您尝试复制它。如果您无法快速复制它,请忽略它。
我知道这听起来很糟糕,但我认为这是有道理的。复制别人发现的错误所需的时间非常长。如果该错误是真实的,它将自然再次发生。有人,甚至您,都会再次跌倒。如果很难复制,那么它也是很少见的,如果再重复几次,可能不会造成太大的损害。
如果您花时间在实际上工作,修复其他错误并编写新代码,则可能会比尝试复制甚至无法保证实际存在的神秘错误要多得多。只需等待它再次自然出现,您就可以花费所有时间修复它,而不用浪费时间尝试揭示它。
要求用户为您的计算机提供远程访问权限,然后自己查看一切。要求用户制作一个关于如何重现此错误的小视频,并将其发送给您。
当然,这两种方法并非总是可能的,但是如果可以的话,这可能会澄清一些事情。查找错误的常见方法仍然是相同的:分离可能导致错误的部分,试图了解正在发生的事情,缩小可能导致错误的代码空间。
有诸如gotomeeting.com之类的工具,可用于与用户共享屏幕并观察行为。可能存在许多潜在问题,例如计算机上安装的软件数量,某些工具实用程序与您的程序冲突。我相信,不是唯一的解决方案,但是可能存在超时问题,网络缓慢问题。
多数情况下,我会说软件不会向您报告正确的错误消息,例如,在java和c#跟踪每个异常的情况下。不要捕获所有异常,而要保留一个可以捕获和记录日志的位置。除非使用远程桌面工具,否则很难解决UI Bug。而且大多数情况下,即使是第三方软件也可能是错误。
如果您使用的是真正的大型应用程序,则可能会有1,000个错误的队列,其中大多数肯定是可重现的。
因此,恐怕我可能会以WORKSFORME(Bugzilla)的身份关闭该错误,然后继续修复一些更明显的错误。或做任何项目经理决定做的事情。
即使进行了局部更改,当然进行随机更改也是一个坏主意,因为您可能会引入新的错误。