我从事软件开发已有二十多年,使用C,Perl,SQL,Java,PHP,JavaScript和最近的Python进行编程.我从来没有遇到过一些问题,我无法通过一些仔细的思考调试,并且调试良好的调试print
语句.
我尊重很多人说我的技术是原始的,在IDE中使用真正的调试器要好得多.然而根据我的观察,IDE用户似乎没有使用我的石刀和熊皮进行更快或更成功的调试.我真诚地愿意学习正确的工具,我从未被证明使用可视化调试器具有令人信服的优势.
此外,除了如何设置断点和显示变量内容的基础知识之外,我从未阅读过如何使用IDE有效调试的教程或书籍.
我错过了什么?是什么让IDE调试工具比周到使用诊断print
语句更有效?
您能否建议显示更好的IDE调试技术的资源(教程,书籍,截屏视频)?
甜蜜的答案!非常感谢大家花时间.非常有启发性.我投了很多票,并且没有投票.
一些值得注意的要点:
调试器可以帮助我对变量,代码或运行时环境的任何其他方面进行临时检查或更改,而手动调试则需要我停止,编辑和重新执行应用程序(可能需要重新编译).
调试器可以附加到正在运行的进程或使用崩溃转储,而通过手动调试,"重现"缺陷的步骤是必要的.
调试器可以以更易读的方式轻松地显示复杂的数据结构,多线程环境或完整的运行时堆栈.
调试器提供了许多方法来减少执行几乎所有调试任务的时间和重复性工作.
可视调试器和控制台调试器都很有用,并且有许多共同的特性.
集成到IDE中的可视化调试器还使您可以在单个集成开发环境(即名称)中方便地访问IDE的智能编辑和所有其他功能.
LeopardSkinP.. 108
IDE调试器将通过代码为您提供跟踪消息的一些功能的一些示例:
在任何时间点查看调用堆栈,为您提供当前堆栈帧的上下文.
进入为无法添加跟踪而无法重新编译的库(假设您可以访问调试符号)
在程序运行时更改变量值
编辑并继续 - 在代码运行时更改代码并立即查看更改结果的功能
能够观察变量,看看它们何时发生变化
能够跳过或重复代码段,以查看代码的执行方式.这允许您在制作之前测试理论变化.
实时检查内存内容
在抛出某些异常时提醒您,即使它们由应用程序处理.
有条件的断点 ; 仅在特殊情况下停止应用程序以允许您分析堆栈和变量.
查看多线程应用程序中的线程上下文,这可能很难通过跟踪实现(因为来自不同线程的跟踪将在输出中交错).
总之,print语句(通常)是静态的,如果原始语句不够详细,则需要重新编译以获取其他信息.IDE将删除此静态屏障,为您提供动态工具包.
当我第一次开始编码时,我无法理解调试器的重要性是什么,我认为我可以通过跟踪实现任何功能(授权,那是在unix上,而调试器是GDB).但是一旦你学会了如何正确使用图形调试器,你就不想再回到打印语句了.
IDE调试器将通过代码为您提供跟踪消息的一些功能的一些示例:
在任何时间点查看调用堆栈,为您提供当前堆栈帧的上下文.
进入为无法添加跟踪而无法重新编译的库(假设您可以访问调试符号)
在程序运行时更改变量值
编辑并继续 - 在代码运行时更改代码并立即查看更改结果的功能
能够观察变量,看看它们何时发生变化
能够跳过或重复代码段,以查看代码的执行方式.这允许您在制作之前测试理论变化.
实时检查内存内容
在抛出某些异常时提醒您,即使它们由应用程序处理.
有条件的断点 ; 仅在特殊情况下停止应用程序以允许您分析堆栈和变量.
查看多线程应用程序中的线程上下文,这可能很难通过跟踪实现(因为来自不同线程的跟踪将在输出中交错).
总之,print语句(通常)是静态的,如果原始语句不够详细,则需要重新编译以获取其他信息.IDE将删除此静态屏障,为您提供动态工具包.
当我第一次开始编码时,我无法理解调试器的重要性是什么,我认为我可以通过跟踪实现任何功能(授权,那是在unix上,而调试器是GDB).但是一旦你学会了如何正确使用图形调试器,你就不想再回到打印语句了.
IDE调试器允许您在运行时更改变量的值.
通过IDE调试器,您可以查看执行开始时您不想知道的变量值.
IDE调试器允许您查看调用堆栈并检查传递奇怪值的函数的状态.(想想这个函数是从数百个地方调用的,你不知道这些奇怪的值来自哪里)
IDE调试器允许您根据条件而不是行号有条件地在代码中的任何位置中断执行.
IDE调试器将允许您在未处理的异常情况下检查程序的状态,而不仅仅是破解.
这是你用"print"语句无法调试的一件事,就是当客户给你带来内存转储并说"你的程序崩溃了,你能告诉我为什么吗?"
通过代码打印语句会降低可读性.
仅出于调试目的添加和删除它们非常耗时
调试器跟踪调用堆栈,使您可以轻松查看自己的位置
变量可以动态修改
可以在执行暂停期间执行临时命令以辅助诊断
可以在IN CONJUNCTION中使用print语句:Debug.Write("...")
我认为使用print语句进行调试是一种迷失的艺术,对每个开发人员来说都非常重要.一旦你知道如何做到这一点,某些类的错误比通过IDE更容易调试.知道这种技术的程序员也非常清楚地知道什么是有用的信息放在日志消息中(更不用说你实际上最终会读取日志)以用于非调试目的.
也就是说,你真的应该知道如何使用逐步调试器,因为对于不同类别的错误,它更容易.我将把它留给已经发布的其他优秀答案来解释为什么:)
脱离我的头顶:
调试复杂对象 - 调试器允许您深入到对象的内部.如果你的对象有一个复杂对象数组的数组,那么print语句只会让你到目前为止.
跳过代码的能力 - 调试器还允许您跳过您不想执行的代码.没错,您也可以手动执行此操作,但是您必须注入更多代码.