记一个调试了两个小时的 Bug

数个月前,我为了解决通过 Sails 把文件上传到七牛的问题,写了一个小小的轮子来解决这个问题。然而,今天就是这个玩意让我调试了两个小时。

问题是这样子的。

当上传文件的时候,如果取消请求,那么整个进程都会崩溃。

错误如下。

顿时就傻了。前面两级是 Node 的内核..

不不不存在的。还是先考虑自己的问题。

在报错点打了个断点然后往下单步跟踪。

首先直接报错点是这儿..原因是 cb 此时是 null。

顺手一个 Google, 找到了这个issue。看楼下的意思是,node 已经对这个 cb 进行了判断并且在非法的情况下赋予了默认值,不会出现错误。

OAO……

事实证明这个 issue 给了我很大的误导。

往前看看,在调用这个 cb 之前 node 都干了啥。

从这里的变量跟踪可以看出,state.writecb 是 null,导致了后面 cb 是 null。其实一开始我没注意到这点,而是注意到了下面那个 onwriteStateUpdate 函数。

346行,把 state.writecb 赋值为了 null。

OAO……你为什么要这么做。

一开始我真觉得就是这个的锅了,百思不得其解。我是怎么转过弯来的我也给忘了。

这里讲一下正常的推理过程。

首先,onwrite 函数取出了 state.writecb,然后调用 onwriteStateUpdate 函数清空了 state.writecb 。这一过程理论上并不会影响到 cb 的值的获取。但是,问题就是,我调用了这个函数两次。

……你们不要笑!这是失误!

这个 next 函数是自定义 Writable._write 方法时的最后一步。查阅 Node 文档可以知道 _write 中的 callback 方法(这里我叫了 next )在每个 Chunk 处理完调用。第二次调用的时候,state.writecb 已经被 onwriteStateUpdate 函数清空,而 Node 在这里并没有加以检验,导致了致命的错误。

好的吧。我的锅。

发表评论

电子邮件地址不会被公开。 必填项已用*标注