03 August 2014

我发现,当一个程序没有好的调试手段时,出了问题解决起来就比较费劲。而当我找到好的调试方法时,问题解决的效率就会上一个台阶。

已发现的,需要特殊的手段才能调试的场景有:IE6和iPad上的JS bug,nodejs代码bug,数据库存储过程的bug。

nodejs 代码调试

nodejs应用分为两种,一种是纯粹javascript代码,不涉及系统io/fs库调用的代码,比如用UglifyJS处理源文件,这种场景的调试方法就是:把代码放到chrome环境里面去打断点调试。

另外一种就是涉及到io/fs等底层库调用的nodejs代码,这种场景我的经验是,用node-inspector工具进行调试,但是被调试的代码要特殊处理。

策略如下,以调试本地编译程序compile为例:

//module.exports = compile; //正常的代码
var http = require("http");
module.exports = function(params){
    //这里专门启动了一个http server,以便调试
    http.createServer(function(req, res){
        compile(params);
        res.end("hello world");
    }).listen(8787);
};

原本正常的代码是第一行module.export = compile,为了能在进入compile之前打断点,这里把入口程序改成了一个启动http server,收到http请求之后再进入原来的入口程序。这样,在把入口nodejs文件传给node执行之后,在浏览器端访问node-inspector的调试页面,才能对上面的第6行打断点。然后再用浏览器访问http://127.0.0.1:8787/,程序执行到第6行并暂停,这样就可以对compile函数进行可视化的单步调试了。

node-inspector debug hack

目前我发现,只能先在被调试代码里面启动http server,才能使用node-inspector进行调试。

当然,webstorm也可以调试nodejs,不用额外启动http server,但是调试复杂的,本身就很消耗资源的nodejs代码时,很容易卡住,而且提供的调试信息也不如node-inspector友好。

IE6/7上的JS调试

装office 2007的时候,顺便安装microsoft script debugger。这样js有错误时可以直接进入script debugger里面进行调试。

或者把调试信息输出到页面中的某个冗余的html元素上进行查看。

var logArr = [];
var console = {};
console.log = function(log){
    logArr.push(log);
    div.innerHTML = logArr.join("<br/>");
}

iPad/手机网页上的JS调试

把js的调试信息用http请求发送到某个服务器上,然后到服务器上查看浏览器上发过来的调试信息。

var console = {};
console.log = function(log){
    var xhr = new XMLHttpRequest();
    xhr.open("http://127.0.0.1:8080/","GET", false);
    xhr.send(log);
}

上面是个例子,当然正式调试时不是每次调console.log就发送,而是间隔几秒再发送。

数据库存储过程的调试

我不是专门做存储过程开发的,只说一下我在这方面的调试经验。

碰到的问题是:对一张表的test_date列的值在(20140802151517,20140802152223)之间的行,求满足这个条件的所有行的列remaining的平均值。remaining列的格式是查询字符串的形式,即A=123&B=456&C=789。每个行的remaining列的内容都应该是A=xxx&B=yyy&C=zzz的格式,要计算所有符合条件的行的remaing列中A的平均值avgA,B的平均值avgB,C的平均值avgC,输出格式为A=avgA&B=avgB&C=avgC。

有一个存储过程count_avg_remaining就是专门用于实现这个需求的。它的输入是列test_date的过滤条件start_date和end_date。现在在输入条件20140802151517和20140802152223下报sql错误,但无法从sql错误中识别问题所在。

最后的调试手段就是,对输入条件进行二分,逐渐缩小输入条件,最终定位到导致了报错的行,发现该行的remaing列格式不对。

想到之前个人中心后台组的同事说php页面打开慢,问题定位方法:先注释掉php代码的前半部分,保留后半部分,看是否打开速度变快了。如果不是,那注释掉后半部分的代码,保留前半部分代码再看看。逐渐递归,最终定位到导致打开慢的代码所在行。

花絮

没做过andriod和ios开发,很好奇这些运行在“客户端”上的代码是如何调试的。

理想的开发语言,就应该像Java那样,有成熟的的开发、调试(甚至线上调试)、部署、监控和性能测试profile工具。


没有更多了



blog comments powered by Disqus