2019独角兽企业重金招聘Python工程师标准>>>
linux平台下。
一个程序总是运行个两三天,或者一两天的时候突然崩溃了,以前发过一个讨论但是也没找到解决办法,使用的数据库是SQLITE
使用GDB跟踪程序,结果找到了崩溃的地方却显示栈被破坏显示不出调用的具体方法,运行了好几次都是这样。定位到了 __memmove_ssse3在libc里面。
为了恢复完整的栈信息在国外大牛那里找来两句话
(gdb)set $pc=*(void **)$esp
(gdb)set $esp=$esp+4
执行完就可以查看堆栈了(32位平台)。注意这个不能由core文件进入gdb,必须只能是运行着的程序崩溃被gdb捕捉到才行。
查看堆栈看到了出错了地点
void xxx::execsql(QString sql)
{
QMutexLocker locker(&this->readlock);
QSqlQuery query(this->database); //运行到这里崩溃了
if(query.exec(sql)) ...
...
}
程序多线程向数据库插入数据,尽管我已经很小心地处理线程了,但是运行到未来某一时刻还是会崩溃。
直到我又等了两三天测试,测试要看机缘啊,有时候它完全正常工作啊,有时候会崩溃。 结果就是这个方法执行的很频繁,而且同一时刻只有一个线程在访问数据库,但是这句话会崩溃。原因我还没有具体知道,我的推测: 因为在堆栈里面显示QSqlQuery里有数据库资源的申请与释放,在申请资源的时候出错了直接崩溃了。
然后我就将query提升为类成员,代码变成如下了。
void xxx::execsql(QString sql)
{
QMutexLocker locker(&this->readlock);
if(this->query->exec(sql))
...
...
}
再运行,好了。
这个问题仅在多线程(即使加了锁)且操作数据库频繁的时候才会出现,其他情况下则运行良好。