libqxt的当前版本有这样一个问题, 当客户端浏览器未等待服务器返回回复页面时就直接断开连接的话,会引起 段错误,导致整个WebService崩溃。
具体的问题,可这样触发:
1. 在 代码 中 创建 一个WebService实例,这个WebService不会立即返回自己的响应,而是 先要去异步地查询某些数据,例如向另一台第三方WebService查询数据 ,再向客户端回发响应内容。
2. 使用火狐 来访问这个WebService,并且猛击F5,疯狂地刷新。这将导致 WebService里底层的libqxt库频繁地释放旧的请求实例,而创建新的请求实例。具体代码 在:qxtabstracthttpconnector.cpp的getNextRequestID函数里,注册新的请求对象;qxtabstracthttpconnector.cpp的doneWithRequest函数里,释放已经断开连接的请求对象。
3. 当WebService实例从第三方查询到数据,准备向之前自己收到的请求对象返回响应内容时 。 由于之前的请求对象已经被libqxt底层库释放,所以底层库在处理这个回发事件时,会找不到对应的请求实例。而底层库没有处理这种异常情况,导致内存非法访问 。具体代码 在, qxthttpsessionmanager.cpp的processEvents函数里,这一句: QIODevice * device = connector()->getRequestConnection(requestID);对于已经提前断开的连接,返回的device将会是0,表示该连接已经断开。
以及这一句: QxtMetaObject ::connect(device, SIGNAL (bytesWritten( qint64 )), state. onBytesWritten , Qt :: QueuedConnection );由于device为0,所以这一句会引起非法内存访问,产生段错误,然后整个程序崩溃。
妳可以狂按火狐的F5试一试妳自己实现的WebService是否也存在这种问题。产生 这种问题的关键在于,所实现的WebService实例要是异步回发响应的,而不是在indexRequested函数里直接回发响应的。
以上是本座调查得到的结论。接下来本座将尝试修复一下这个问题。
李孝利
HxLauncher: Launch Android applications by voice commands