linux平臺下。 linux
一個程序老是運行個兩三天,或者一兩天的時候忽然崩潰了,之前發過一個討論可是也沒找到解決辦法,使用的數據庫是SQLITE sql
使用GDB跟蹤程序,結果找到了崩潰的地方卻顯示棧被破壞顯示不出調用的具體方法,運行了好幾回都是這樣。定位到了 __memmove_ssse3在libc裏面。 數據庫
爲了恢復完整的棧信息在國外大牛那裏找來兩句話 多線程
(gdb)set $pc=*(void **)$esp (gdb)set $esp=$esp+4
執行完就能夠查看堆棧了(32位平臺)。注意這個不能由core文件進入gdb,必須只能是運行着的程序崩潰被gdb捕捉到才行。 測試
查看堆棧看到了出錯了地點 this
void xxx::execsql(QString sql) { QMutexLocker locker(&this->readlock); QSqlQuery query(this->database); //運行到這裏崩潰了 if(query.exec(sql)) ... ... }
程序多線程向數據庫插入數據,儘管我已經很當心地處理線程了,可是運行到將來某一時刻仍是會崩潰。 spa
直到我又等了兩三天測試,測試要看機緣啊,有時候它徹底正常工做啊,有時候會崩潰。 結果就是這個方法執行的很頻繁,並且同一時刻只有一個線程在訪問數據庫,可是這句話會崩潰。緣由我尚未具體知道,個人推測: 由於在堆棧裏面顯示QSqlQuery裏有數據庫資源的申請與釋放,在申請資源的時候出錯了直接崩潰了。 .net
而後我就將query提高爲類成員,代碼變成以下了。 線程
void xxx::execsql(QString sql) { QMutexLocker locker(&this->readlock); if(this->query->exec(sql)) ... ... }
再運行,好了。 code
這個問題僅在多線程(即便加了鎖)且操做數據庫頻繁的時候纔會出現,其餘狀況下則運行良好。