我正在處理我懷疑在使用QNetworkAccessManager
期間發生的程序中發生的堆棧損壞錯誤。完整的源代碼可用here。使用QNetworkAccessManager期間可能的堆棧損壞
從日誌輸出來判斷,我猜測這個bug是在calendar.cpp的第44行的異步請求之後觸發的。我沒有這方面的確鑿證據;我只注意到第45行的消息是大多數時間最後的日誌消息。
這裏是線39-46:
void Calendar::update()
{
// Start calendar download asynchronously. After retrieving the
// file, parseNetworkResponse will take over.
Logger::instance()->add(CLASSNAME, "Fetching update for 0x" + QString::number((unsigned)this, 16) + "...");
_naMgr.get(QNetworkRequest(_url));
Logger::instance()->add(CLASSNAME, "Update request for 0x" + QString::number((unsigned)this, 16) + " was filed.");
}
該HTTP GET請求由Calendar::parseNetworkResponse
插槽,其被連接到_naMgr
的finished
信號處理。下面是線170-174:
void Calendar::parseNetworkResponse(QNetworkReply* reply) {
// TODO: we suspect that sometimes a SIGSEGV occurs within the bounds
// of this function. We'll remove the excessive log calls when we've
// successfully tracked down the problem.
Logger::instance()->add(CLASSNAME, "Got update response for 0x" + QString::number((unsigned)this, 16) + ".");
即使上線45日誌消息不是最後出現在日誌崩潰後,總有在日誌中的更新請求是永遠不會跟進通過第174行的日誌消息。這使我相信,HTTP GET請求可能會破壞這裏的東西。 GET請求提交的URL似乎是正確的。
我認爲存在內存損壞的原因之一是,即使輸入日曆列表和我的Internet連接狀態保持不變,該錯誤並不會始終彈出。 (我可以用至少2個日曆觸發bug。)此外,當我嘗試瞭解更多關於失敗點的信息時,我看到了this GCC output。我會從valgrind
的內存檢查器收集輸出以收集更多信息,但目前我附近沒有可用的Linux安裝。
這個bug可能與我身邊的Qt網絡庫的錯誤使用有關嗎?你有什麼其他的理論可能會導致這個問題?這是我第一次處理可能的堆棧損壞問題,因爲在業餘時間我正在做這個單獨的愛好項目,所以我沒有人來訓練我解決這些問題。
我認爲'Calendar :: parseNetworkResponse'總是在接收線程上執行,因爲我的['Qt :: ConnectionType'](http://qt-project.org/doc/qt-4.8/qt.html#ConnectionType-枚舉)設置爲'Qt :: AutoConnection'。這是不是意味着'Calendar :: parseNetworkResponse'永遠不會同時在多個線程中執行?或者也許我不太瞭解'QNetworkAccessManager'的內在機制。 – Pieter 2012-08-19 10:40:25
它背後有很多東西。我寫了一個使用它的非常複雜的程序。我在這裏從這個網站學到了很多:http://www.johanpaul.com/blog/2011/07/why-qnetworkaccessmanager-should-not-have-the-finishedqnetworkreply-signal/ – FaddishWorm 2012-08-19 10:42:58
就像我之前說的那樣,它總是很好有一個這種東西的包裝類:) – FaddishWorm 2012-08-19 10:43:14