简介
可能是目前为止最全的调试指南
前言
在编程开发的过程中总会遇到一些迷人的BUG,最近几个人来找我帮忙DEBUG,都是很难通过搜索引擎解决的问题。最后发现都是很神奇的错误,于是决定写一篇文章好好来聊一聊如何DEBUG。
0 整体思路
总的来说,问题的本质是预期结果A与实际结果B不符。这个时候就要DEBUG了,下文将以本人DEBUG的经验说一说DEBUG的原则,以及从不同的平台来聊一聊如何DEBUG。
调试条件:
– 有预期结果
– 结果可观测
(注意一些薛定谔的结果,试图观测可能会破坏原有状态)
基本方法:
– 控制变量
– 二分法查找
所以只要让结果可观测,那么就可以借此定位出现问题的部分在哪。一般来说都是打印日志或者IDE断点
0.1 分解问题
当遇到BUG的时候,从结果出发分析结果出现的过程,追溯到输入。一般来说,都是输入经过n个处理流程后得到最后出现的结果。
0.2 定位问题
从结果开始追溯,观测每个阶段结果,从而确定从哪个流程开始结果开始不对的。
0.3 设计方案
设法观测中间结果,使结果可观测。
设法改变出问题阶段的输出恒为正确答案,观测最终结果是否正确。
如果正确,说明该流程后面的流程都没问题,继续向前定位。
如果不正确,说明后面的流程至少有一个有问题,继续向后定位。
1 Web端调试
常用工具为Chrome的F12的开发人员调试工具。
APP上的内嵌网页如果需要依赖APP则使用Remove device功能
一般网页的加载过程:浏览器接收HTTP报文,解析HTML并渲染,加载JS、CSS等静态资源,解析JS脚本并执行。
1.1 html
HTML最终结果的调试在elements标签中可以动态更改,查看效果。
前后端分离的项目大多是JS来渲染DOM并填充数据,所以DOM是动态生成的,需要查看原始的source,而不是elements
1.2 js
JS在source中可以寻找源码,添加断点,单步调试。
1.3 css
CSS的调试在style窗口可以动态修改样式。
2.移动端调试(Android/iOS)
移动端的调试大多依赖对应的IDE,以Android为例,Android Studio支持真机下断点进行调试,logcat可以输出调试日志。当然也有一些手机上的sqlite可视化工具可以使用。
也可以改写代码将中间结果图形化直接显示到界面上,或者弹出提示窗进行显示。
3 API调试
API大部分都是基于HTTP协议的,只要抓住HTTP报文,一般问题都可以解决。
API调试可以借助Chrome开发工具的Network标签,可以详细显示HTTP协议的header和body。自带json格式化。拦截对应的HTTP请求,分析请求过程。
如果Chrome开发工具搞不定,可以使用Postman模拟构造HTTP报文来发送请求,当然也可以使用curl生成自定义的HTTP报文。
如果上面的工具依然难以调试,则可以选择设置流量代理或者借助其他软件拦截所有网络流量包分析过程。
4 Server端调试
服务端调试大部分情况下依赖于日志
tail -f filename.log可以持续查看一个文件的变化,用于监控日志非常方便。
4.1 接入层调试
nginx apache有对应的请求日志和加载日志,直接对应查看即可。
如果转发有误则可以考虑放测试文件到对应的文件夹下来测试转发。
4.2 应用层调试
不同的应用服务器也有自己的启动日志和运行日志,可供调试参考。
如果在开发环境下,可以直接借助IDE进行断点调试,追踪问题。如果在特殊环境无法加载IDE,则最简单的办法依然是打印详细日志来追踪程序执行过程,缩小并确定问题范围。
注意未知因素的影响,例如有些框架取数据是自动拼接方法名并调用来取值,注意避开这些自动生成的方法名以免冲突。
5 Linux调试
Linux下的调试大部分都没有图形界面,只能看字符输出,所以多打印中间结果总能找到出问题的部分。
5.1 shell脚本调试
利用echo打印中间结果或使用sh -x参数进行调试。
5.2 shell命令调试
shell命令是在环境变量PATH中搜索的,一般使用which可以查看到命令的可执行文件所在位置,并继续跟踪执行过程即可。
5.3 网络调试
网络出现问题时候可以使用ping和traceroute来追中出问题的网络节点,使用netstat -ano查看端口占用情况。
6 特定语言调试
其实也没什么特殊的,除了借助IDE的断点调试之外,各个语言都有自带的打印函数可以打印中间结果。
6.1 C/C++
printf cout
6.2 Java
System.out.println
Log4j框架
6.3 Python
print
logging和traceback模块
7 常见错误
7.1 环境错误
开发环境本身配置有误,没有完成测试就继续开发了,避免方法是提前做好环境测试。运行测试的DEMO
7.2 语法错误
IDE一般会提示的,不解释
7.3 拼写错误
手残不解释
7.4 逻辑错误
这类错误是最常见的,也最难调试。也就是所有语法都对,但是结果不对,说明代码逻辑有问题,解决方法就是上面所说的逐步缩小范围,直到一行代码。
7.5 调试的错误
调试本身的错误,由于某些情况下的薛定谔效应无法直接观测结果,只能间接观察的时候容易引起人的误判。想办法避免直接观测即可。
7.6 其他错误
程序都对,但是某配置文件有错,比如makefile文件只能用tab。yaml中只能用空格。python中tab和空格的混用。某些print不支持中文等。
0 Comments