cde*_*zaq 63 debugging replicate
问题就是这一切.如果您有多个用户报告的错误,但没有记录日志中发生的错误,也不能重复该错误,无论您如何努力,您如何解决?甚至可以吗?
我相信你们当中很多人都会遇到这种情况.你在这种情况下做了什么,最终的结果是什么?
编辑:我对一个不可修复的错误做了什么感兴趣,而不是一个无法解决的错误.无法解决的错误使得您至少知道存在问题并且在大多数情况下具有搜索它的起点.如果是不可能的,你做什么?你甚至可以做任何事情吗?
Dav*_*vis 78
这些被称为Heisenbugs.
不同的编程语言会有各自的错误.
添加调试语句可能会使问题无法复制,因为调试语句本身会移动指针(足以避免SEGFAULT).指针问题是跟踪和复制的噩梦,但有些调试器(如GDB和DDD)可以提供帮助.
具有多个线程的应用程序可能仅显示具有非常特定的时间或事件序列的错误.不正确的并发实现可能会在难以复制的情况下导致死锁.
一些Web浏览器因内存泄漏而臭名昭着.在一个浏览器中运行良好的JavaScript代码可能会在另一个浏览器中导致错误行为 使用经过数千名用户严格测试的第三方库可能有利于避免某些模糊的错误.
根据应用程序(具有错误)运行的环境的复杂性,唯一的办法可能是简化环境.应用程序是否运行:
应用程序在什么环境中产生问题?
退出无关应用程序,终止后台任务,停止所有计划事件(cron作业),消除插件并卸载浏览器加载项.
因为网络对于这么多应用程序至关重要:
消除尽可能多的未知数:
删除生产,测试和开发之间的所有差异.使用相同的硬件.完全按照完全相同的步骤来设置计算机.一致性是关键.
使用大量的日志记录来关联发生的时间事件.检查日志是否有任何明显的错误,时间问题等.
如果软件似乎没问题,请考虑硬件故障:
主要用于嵌入式:
在本地运行应用程序(即不通过网络)会发生什么?其他服务器是否遇到同样的问题?数据库是远程的吗?你能使用本地数据库吗?
在硬件和软件之间是固件.
时间问题很难跟踪:
收集有关问题的硬数值数据.一开始可能出现随机的问题可能实际上有一种模式.
有时系统升级后会出现问题.
不同的操作系统有不同的方式来分配冲突的库:
执行全新安装的操作系统,仅包括应用程序所需的支持软件.
确保每个库仅使用一次.有时,应用程序容器具有与应用程序本身不同的库版本.这可能无法在开发环境中进行复制.
对错误发生时触发通知(例如,日志,电子邮件,弹出窗口,寻呼机蜂鸣声)的检测方法进行编码.使用自动化测试将数据提交到应用程序中.使用随机数据.使用涵盖已知和可能的边缘情况的数据.最终这个bug应该重新出现.
值得重申其他人所提到的:睡在上面.花时间远离问题,完成其他任务(如文档).远离电脑并进行锻炼.
逐行浏览代码,并描述每行对自己,同事或橡皮鸭做的事情.这可能会导致对如何重现错误的见解.
宇宙射线可以翻转位.由于内存的现代错误检查,这不像过去的问题那么大.离开地球保护的硬件软件受到由于宇宙辐射的随机性而无法复制的问题.
很少发生,但特别是对于利基工具(例如,遭受符号表溢出的C微控制器编译器).
Bri*_*new 13
如果它是一个GUI应用程序,那么观察客户生成错误(或尝试)是非常宝贵的.毫无疑问,他们正在做一些你从未猜到过他们正在做的事情(不是错误的,只是不同的).
否则,请将您的日志记录集中在该区域.记录大部分内容(您可以稍后将其删除)并让您的应用程序也转储其环境.例如机器类型,VM类型,使用的编码.
您的应用报告版本号,内部版本号等吗?您需要这个来确定您正在调试的版本(或不是!).
如果您可以检测您的应用程序(例如,如果您在Java世界中使用JMX),那么请检测相关区域.存储统计信息,例如请求+参数,时间等.利用缓冲区存储最后的'n'个请求/响应/对象版本/等等,并在用户报告问题时将其转储出去.
如果您无法复制它,您可能会修复它,但无法知道您已修复它.
我已经最好地解释了错误是如何被触发的(即使我不知道这种情况会如何发生),修复了这个问题,并确保如果错误再次出现,我们的通知机制会让未来的开发人员知道我希望我知道的事情.实际上,这意味着在可能触发错误的路径被越过时添加日志事件,并记录相关资源的度量标准.当然,确保测试能够很好地运用代码.
确定要添加的通知是可行性和分类问题.因此,首先要决定开发人员花在bug上的时间.如果不知道bug有多重要,就无法回答.
我有很好的结果(没有再出现,代码更好),而且很糟糕(花了太多时间没有修复问题,bug是否已经修复了).这就是估计和问题优先考虑的因素.
有时我只需坐下来研究代码,直到找到错误.试着证明这个bug是不可能的,在这个过程中你可能会弄清楚你可能会弄错的地方.如果你真的成功地说服自己这是不可能的,那么假设你搞砸了某个地方.
添加一堆错误检查和断言以确认或否定您的信念/假设可能会有所帮助.有些东西可能会失败,你永远不会想到.
这可能很困难,有时几乎不可能.但我的经验是,如果你花了足够的时间(如果花费的时间是值得的,那么你将迟早能够重现并修复bug)是另一回事.
一般建议可能有助于这种情况.
假设您已经添加了您认为有帮助的所有日志记录,但它没有帮助……我想到了两件事:
从报告的症状开始倒推。想一想..“如果我想产生所报告的症状,我需要执行哪些代码,我将如何实现它,以及我将如何实现它?” D 导致 C 导致 B 导致 A。接受这样的事实:如果错误不可重现,那么普通方法将无济于事。我不得不盯着代码好几个小时,不断地思考才能发现一些错误。通常情况下,事实证明这是非常愚蠢的事情。
记住鲍勃的调试第一定律:如果你找不到某些东西,那是因为你找错了地方:-)
思考。难的。把自己锁起来,不许任何打扰。
我曾经遇到过一个错误,其证据是损坏数据库的十六进制转储。指针链被系统地搞乱了。所有用户的程序以及我们的数据库软件在测试中都运行良好。我盯着它看了一周(这是一个重要的客户),在排除了数十种可能的想法后,我意识到数据分布在两个物理文件中,并且损坏发生在链跨越文件边界的地方。我意识到,如果备份/恢复操作在关键点失败,两个文件最终可能会“不同步”,恢复到不同的时间点。如果您随后在已经损坏的数据上运行客户的程序之一,它将准确地生成我所看到的打结的指针链。然后,我演示了一系列事件,准确地再现了损坏情况。
归档时间: |
|
查看次数: |
20864 次 |
最近记录: |