Valgrind报告sqlite3_step中未初始化的值
Valgrind reports uninitialised value(s) in sqlite3_step
我正在编写一个多线程c++应用程序,将数据写入sqlite数据库。一个线程处理数据库事务,其他线程收集数据或更新显示,因此不存在数据库或sqlite函数的多线程使用。我的问题是,Valgrind Memcheck在数据库线程中使用未初始化的值时给出了以下输出(更新:请参阅最后的完整调试信息输出):
Thread 6:
Conditional jump or move depends on uninitialised value(s)
==15356== at 0x35A7A0C7FE: ??? (in /usr/lib64/libsqlite3.so.0.8.6)
==15356== by 0x35A7A6994E: ??? (in /usr/lib64/libsqlite3.so.0.8.6)
==15356== by 0x35A7A5655F: sqlite3_step (in /usr/lib64/libsqlite3.so.0.8.6)
==15356== by 0x478CE2: MyClass::MyFunction(...) (MyClass.cpp:576)
... (rest of the call stack)
(previous section two more times)
Syscall param write(buf) points to uninitialised byte(s)
==15356== at 0x35956DB79D: ??? (syscall-template.S:82)
==15356== by 0x35A7A1E8BD: ??? (in /usr/lib64/libsqlite3.so.0.8.6)
==15356== by 0x35A7A16ECE: ??? (in /usr/lib64/libsqlite3.so.0.8.6)
==15356== by 0x35A7A25EC3: ??? (in /usr/lib64/libsqlite3.so.0.8.6)
==15356== by 0x35A7A26178: ??? (in /usr/lib64/libsqlite3.so.0.8.6)
==15356== by 0x35A7A3C16E: ??? (in /usr/lib64/libsqlite3.so.0.8.6)
==15356== by 0x35A7A6C915: ??? (in /usr/lib64/libsqlite3.so.0.8.6)
==15356== by 0x35A7A5655F: sqlite3_step (in /usr/lib64/libsqlite3.so.0.8.6)
==15356== by 0x47B470: MyClass::MyFunction(...) (MyClass.cpp:721)
... (rest of the call stack - no space between these outputs)
Address 0x4ed2a88 is 1,208 bytes inside a block of size 1,280 alloc'd
==15356== at 0x4A069EE: malloc (vg_replace_malloc.c:270)
==15356== by 0x35A7A1DD61: ??? (in /usr/lib64/libsqlite3.so.0.8.6)
==15356== by 0x35A7A09368: ??? (in /usr/lib64/libsqlite3.so.0.8.6)
==15356== by 0x35A7A09447: ??? (in /usr/lib64/libsqlite3.so.0.8.6)
==15356== by 0x35A7A0AC9A: ??? (in /usr/lib64/libsqlite3.so.0.8.6)
==15356== by 0x35A7A241FA: ??? (in /usr/lib64/libsqlite3.so.0.8.6)
==15356== by 0x35A7A17825: ??? (in /usr/lib64/libsqlite3.so.0.8.6)
==15356== by 0x35A7A272FE: ??? (in /usr/lib64/libsqlite3.so.0.8.6)
==15356== by 0x35A7A27477: ??? (in /usr/lib64/libsqlite3.so.0.8.6)
==15356== by 0x35A7A274DE: ??? (in /usr/lib64/libsqlite3.so.0.8.6)
==15356== by 0x35A7A277D9: ??? (in /usr/lib64/libsqlite3.so.0.8.6)
==15356== by 0x35A7A27871: ??? (in /usr/lib64/libsqlite3.so.0.8.6)
Conditional jump or move depends on uninitialised value(s)
==15356== at 0x35A7A0C7FE: ??? (in /usr/lib64/libsqlite3.so.0.8.6)
==15356== by 0x35A7A6994E: ??? (in /usr/lib64/libsqlite3.so.0.8.6)
==15356== by 0x35A7A5655F: sqlite3_step (in /usr/lib64/libsqlite3.so.0.8.6)
==15356== by 0x47B470: MyClass::MyFunction(...) (MyClass.cpp:721)
... (rest of the call stack)
(previous section two more times)
Syscall param write(buf) points to uninitialised byte(s)
==15356== at 0x35956DB79D: ??? (syscall-template.S:82)
==15356== by 0x35A7A1E8BD: ??? (in /usr/lib64/libsqlite3.so.0.8.6)
==15356== by 0x35A7A287A6: ??? (in /usr/lib64/libsqlite3.so.0.8.6)
==15356== by 0x35A7A376E7: ??? (in /usr/lib64/libsqlite3.so.0.8.6)
==15356== by 0x35A7A37906: ??? (in /usr/lib64/libsqlite3.so.0.8.6)
==15356== by 0x35A7A38443: ??? (in /usr/lib64/libsqlite3.so.0.8.6)
==15356== by 0x35A7A6FC80: ??? (in /usr/lib64/libsqlite3.so.0.8.6)
==15356== by 0x35A7A5655F: sqlite3_step (in /usr/lib64/libsqlite3.so.0.8.6)
==15356== by 0x35A7A59AC5: sqlite3_exec (in /usr/lib64/libsqlite3.so.0.8.6)
==15356== by 0x48EDBD: MyClass::commitTransaction() (MyClass.h:659)
... (rest of the call stack - no space between these outputs)
Address 0x4ed2a88 is 1,208 bytes inside a block of size 1,280 alloc'd
==15356== at 0x4A069EE: malloc (vg_replace_malloc.c:270)
==15356== by 0x35A7A1DD61: ??? (in /usr/lib64/libsqlite3.so.0.8.6)
==15356== by 0x35A7A09368: ??? (in /usr/lib64/libsqlite3.so.0.8.6)
==15356== by 0x35A7A09447: ??? (in /usr/lib64/libsqlite3.so.0.8.6)
==15356== by 0x35A7A0AC9A: ??? (in /usr/lib64/libsqlite3.so.0.8.6)
==15356== by 0x35A7A241FA: ??? (in /usr/lib64/libsqlite3.so.0.8.6)
==15356== by 0x35A7A17825: ??? (in /usr/lib64/libsqlite3.so.0.8.6)
==15356== by 0x35A7A272FE: ??? (in /usr/lib64/libsqlite3.so.0.8.6)
==15356== by 0x35A7A27477: ??? (in /usr/lib64/libsqlite3.so.0.8.6)
==15356== by 0x35A7A274DE: ??? (in /usr/lib64/libsqlite3.so.0.8.6)
==15356== by 0x35A7A277D9: ??? (in /usr/lib64/libsqlite3.so.0.8.6)
==15356== by 0x35A7A27871: ??? (in /usr/lib64/libsqlite3.so.0.8.6)
(and so on ...)
Valgrind输出中指向的前两个代码段位于同一个函数中,第三个代码段是从该函数调用的内联函数。Valgrind输出中的第一个代码段(MyClass.cpp:576)如下所示:
// get statement pointer
stmtPtr = getStatementPtr(STATEMENT_INDEX_FOR_THIS_OPERATION);
// reset prepared statement and clear bindings (resetting MUST also be done
// after use - else lock on the database is not released!)
sqlite3_reset(stmtPtr);
sqlite3_clear_bindings(stmtPtr);
// bind directory data to the statement
sqlite3_bind_int(stmtPtr, 1, intValue);
sqlite3_bind_int64(stmtPtr, 2, longIntValue1);
sqlite3_bind_int64(stmtPtr, 3, longIntValue2);
sqlite3_bind_text(stmtPtr, 4, stdString.c_str(), stdString.length(),
SQLITE_STATIC);
sqlite3_bind_int64(stmtPtr, 5, longIntValue3);
sqlite3_bind_int64(stmtPtr, 6, longIntValue4);
sqlite3_bind_int64(stmtPtr, 7, longIntValue5);
sqlite3_bind_int64(stmtPtr, 8, longIntValue6);
sqlite3_bind_int64(stmtPtr, 9, longIntValue7);
// execute statement
result = sqlite3_step(stmtPtr); <= line 576
// handle errors
if (result != SQLITE_DONE)
{
// clean up
cleanUp();
... (error handling code)
}
// reset statement (MUST be done after use - else lock on the database is
// not released!)
sqlite3_reset(stmtPtr);
Valgrind输出中引用的第二段代码(第721行)更简单——我只绑定了两个长int值,否则就类似了。
我将语句指针存储在像这样的映射中:std::map<STATEMENT_INDEX, sqlite3_stmt*> statements_;
并重用它们。每次使用预处理语句时,我首先重置它,然后清除绑定。然后将值绑定到语句并调用sqlite3_step()。在处理意外结果之后,我再次重置语句以释放数据库上的锁。函数cleanup()结束语句并清除映射。
第三段代码(MyClass.h:659)是提交事务的内联函数。这是在前两个部分所在的函数末尾调用的。在函数的开头,我用类似的内联函数开始事务处理。
inline void MyFunction::commitTransaction()
{
// sqlite error handling variables
int result;
char* errMsg = 0;
// execute
result = sqlite3_exec(database_,
"COMMIT TRANSACTION",
0,
0,
&errMsg); <= line 659
// handle errors
if (result != SQLITE_OK)
{
std::string error = std::string(errMsg);
sqlite3_free(errMsg);
clearStatements();
throw MyException("Committing transaction failed: '" + error
+ "'!"LOCATION_LINE);
}
// set flag
transactionOn_ = false;
}
我已经用调试器检查了我绑定到语句的值在sqlite3_step()调用之前真的被初始化了。我还尝试了使用所有绑定值的本地副本并将SQLITE_STATIC更改为SQLITE_TRANSIENT是否会产生任何差异。这些变化没有效果。顺便问一下,可以绑定引用吗?
我也认为语句指针在之前的某个点被最终确定的可能性。结束语句只能通过一个函数来完成,该函数结束映射中的所有语句并清除映射。当映射为空时,再次准备语句。所以我认为这也不是解决办法。
有没有人知道上面Valgrind输出的原因是什么?或者有人能解释为什么Valgrind对相同的发生率给出相同的输出多次?
我使用vgdb服务器调试程序,并在Valgrind输出中提到的行之前设置断点。当我在第一个断点之后继续时,我得到:Program received signal SIGTRAP, Trace/breakpoint trap.
和这行的Valgrind输出。这正是我所期待的。然而,当我在这个休息之后继续时,我又获得了两次相同的SIGTRAP(和输出),并且MyFunction具有相同的函数参数。为什么会这样?
update:我用我的代码编译了最新版本的sqlite3.c(3.8.5)以获得完整的调试信息。这改变了报告的错误,并清除了为什么Valgrind多次给我"相同"的输出。其实不一样,我真傻!所以,这里是Valgrind输出与完整的调试信息:
==1205== Thread 6:
==1205== Conditional jump or move depends on uninitialised value(s)
==1205== at 0x4CDF8E: sqlite3VdbeSerialType (sqlite3.c:64529)
==1205== by 0x4D640E: sqlite3VdbeExec (sqlite3.c:70149)
==1205== by 0x4D0924: sqlite3Step (sqlite3.c:66192)
==1205== by 0x4D0B28: sqlite3_step (sqlite3.c:66258)
==1205== by 0x47B8B3: MyClass::MyFunction(...) (MyClass.cpp:576)
==1205==
==1205== Conditional jump or move depends on uninitialised value(s)
==1205== at 0x4CDFC4: sqlite3VdbeSerialType (sqlite3.c:64536)
==1205== by 0x4D640E: sqlite3VdbeExec (sqlite3.c:70149)
==1205== by 0x4D0924: sqlite3Step (sqlite3.c:66192)
==1205== by 0x4D0B28: sqlite3_step (sqlite3.c:66258)
==1205== by 0x47B8B3: MyClass::MyFunction(...) (MyClass.cpp:576)
==1205==
==1205== Conditional jump or move depends on uninitialised value(s)
==1205== at 0x4CDFD1: sqlite3VdbeSerialType (sqlite3.c:64537)
==1205== by 0x4D640E: sqlite3VdbeExec (sqlite3.c:70149)
==1205== by 0x4D0924: sqlite3Step (sqlite3.c:66192)
==1205== by 0x4D0B28: sqlite3_step (sqlite3.c:66258)
==1205== by 0x47B8B3: MyClass::MyFunction(...) (MyClass.cpp:576)
==1205==
==1205== Conditional jump or move depends on uninitialised value(s)
==1205== at 0x4CE098: sqlite3VdbeSerialTypeLen (sqlite3.c:64561)
==1205== by 0x4D6421: sqlite3VdbeExec (sqlite3.c:70150)
==1205== by 0x4D0924: sqlite3Step (sqlite3.c:66192)
==1205== by 0x4D0B28: sqlite3_step (sqlite3.c:66258)
==1205== by 0x47B8B3: MyClass::MyFunction(...) (MyClass.cpp:576)
==1205==
==1205== Use of uninitialised value of size 8
==1205== at 0x4CE0A9: sqlite3VdbeSerialTypeLen (sqlite3.c:64565)
==1205== by 0x4D6421: sqlite3VdbeExec (sqlite3.c:70150)
==1205== by 0x4D0924: sqlite3Step (sqlite3.c:66192)
==1205== by 0x4D0B28: sqlite3_step (sqlite3.c:66258)
==1205== by 0x47B8B3: MyClass::MyFunction(...) (MyClass.cpp:576)
==1205==
==1205== Conditional jump or move depends on uninitialised value(s)
==1205== at 0x4D6490: sqlite3VdbeExec (sqlite3.c:70162)
==1205== by 0x4D0924: sqlite3Step (sqlite3.c:66192)
==1205== by 0x4D0B28: sqlite3_step (sqlite3.c:66258)
==1205== by 0x47B8B3: MyClass::MyFunction(...) (MyClass.cpp:576)
==1205==
==1205== Conditional jump or move depends on uninitialised value(s)
==1205== at 0x4CDF8E: sqlite3VdbeSerialType (sqlite3.c:64529)
==1205== by 0x4D65F7: sqlite3VdbeExec (sqlite3.c:70198)
==1205== by 0x4D0924: sqlite3Step (sqlite3.c:66192)
==1205== by 0x4D0B28: sqlite3_step (sqlite3.c:66258)
==1205== by 0x47B8B3: MyClass::MyFunction(...) (MyClass.cpp:576)
==1205==
==1205== Conditional jump or move depends on uninitialised value(s)
==1205== at 0x4CDFC4: sqlite3VdbeSerialType (sqlite3.c:64536)
==1205== by 0x4D65F7: sqlite3VdbeExec (sqlite3.c:70198)
==1205== by 0x4D0924: sqlite3Step (sqlite3.c:66192)
==1205== by 0x4D0B28: sqlite3_step (sqlite3.c:66258)
==1205== by 0x47B8B3: MyClass::MyFunction(...) (MyClass.cpp:576)
==1205==
==1205== Conditional jump or move depends on uninitialised value(s)
==1205== at 0x4CDFD1: sqlite3VdbeSerialType (sqlite3.c:64537)
==1205== by 0x4D65F7: sqlite3VdbeExec (sqlite3.c:70198)
==1205== by 0x4D0924: sqlite3Step (sqlite3.c:66192)
==1205== by 0x4D0B28: sqlite3_step (sqlite3.c:66258)
==1205== by 0x47B8B3: MyClass::MyFunction(...) (MyClass.cpp:576)
==1205==
==1205== Conditional jump or move depends on uninitialised value(s)
==1205== at 0x4D6605: sqlite3VdbeExec (sqlite3.c:70199)
==1205== by 0x4D0924: sqlite3Step (sqlite3.c:66192)
==1205== by 0x4D0B28: sqlite3_step (sqlite3.c:66258)
==1205== by 0x47B8B3: MyClass::MyFunction(...) (MyClass.cpp:576)
==1205==
==1205== Conditional jump or move depends on uninitialised value(s)
==1205== at 0x4CE0CC: sqlite3VdbeSerialPut (sqlite3.c:64639)
==1205== by 0x4D6673: sqlite3VdbeExec (sqlite3.c:70200)
==1205== by 0x4D0924: sqlite3Step (sqlite3.c:66192)
==1205== by 0x4D0B28: sqlite3_step (sqlite3.c:66258)
==1205== by 0x47B8B3: MyClass::MyFunction(...) (MyClass.cpp:576)
==1205==
==1205== Conditional jump or move depends on uninitialised value(s)
==1205== at 0x4CE14A: sqlite3VdbeSerialPut (sqlite3.c:64658)
==1205== by 0x4D6673: sqlite3VdbeExec (sqlite3.c:70200)
==1205== by 0x4D0924: sqlite3Step (sqlite3.c:66192)
==1205== by 0x4D0B28: sqlite3_step (sqlite3.c:66258)
==1205== by 0x47B8B3: MyClass::MyFunction(...) (MyClass.cpp:576)
==1205==
==1205== Conditional jump or move depends on uninitialised value(s)
==1205== at 0x4D5D49: sqlite3VdbeExec (sqlite3.c:69927)
==1205== by 0x4D0924: sqlite3Step (sqlite3.c:66192)
==1205== by 0x4D0B28: sqlite3_step (sqlite3.c:66258)
==1205== by 0x47E041: MyClass::MyFunction(...) (MyClass.cpp:722)
==1205==
==1205== Conditional jump or move depends on uninitialised value(s)
==1205== at 0x4CE098: sqlite3VdbeSerialTypeLen (sqlite3.c:64561)
==1205== by 0x4D5DB2: sqlite3VdbeExec (sqlite3.c:69934)
==1205== by 0x4D0924: sqlite3Step (sqlite3.c:66192)
==1205== by 0x4D0B28: sqlite3_step (sqlite3.c:66258)
==1205== by 0x47E041: MyClass::MyFunction(...) (MyClass.cpp:722)
==1205==
==1205== Use of uninitialised value of size 8
==1205== at 0x4CE0A9: sqlite3VdbeSerialTypeLen (sqlite3.c:64565)
==1205== by 0x4D5DB2: sqlite3VdbeExec (sqlite3.c:69934)
==1205== by 0x4D0924: sqlite3Step (sqlite3.c:66192)
==1205== by 0x4D0B28: sqlite3_step (sqlite3.c:66258)
==1205== by 0x47E041: MyClass::MyFunction(...) (MyClass.cpp:722)
==1205==
==1205== Conditional jump or move depends on uninitialised value(s)
==1205== at 0x4CE193: sqlite3VdbeSerialGet (sqlite3.c:64689)
==1205== by 0x4D5FED: sqlite3VdbeExec (sqlite3.c:69990)
==1205== by 0x4D0924: sqlite3Step (sqlite3.c:66192)
==1205== by 0x4D0B28: sqlite3_step (sqlite3.c:66258)
==1205== by 0x47E041: MyClass::MyFunction(...) (MyClass.cpp:722)
==1205==
==1205== Use of uninitialised value of size 8
==1205== at 0x4CE19C: sqlite3VdbeSerialGet (sqlite3.c:64689)
==1205== by 0x4D5FED: sqlite3VdbeExec (sqlite3.c:69990)
==1205== by 0x4D0924: sqlite3Step (sqlite3.c:66192)
==1205== by 0x4D0B28: sqlite3_step (sqlite3.c:66258)
==1205== by 0x47E041: MyClass::MyFunction(...) (MyClass.cpp:722)
==1205==
==1205== Syscall param write(buf) points to uninitialised byte(s)
==1205== at 0x35956DB79D: ??? (syscall-template.S:82)
==1205== by 0x4A980E: seekAndWriteFd (sqlite3.c:27173)
==1205== by 0x4A9886: seekAndWrite (sqlite3.c:27193)
==1205== by 0x4A999A: unixWrite (sqlite3.c:27260)
==1205== by 0x49FEF6: sqlite3OsWrite (sqlite3.c:15755)
==1205== by 0x4B3103: subjournalPage (sqlite3.c:44215)
==1205== by 0x4B4B96: pager_write (sqlite3.c:45624)
==1205== by 0x4B4E57: sqlite3PagerWrite (sqlite3.c:45737)
==1205== by 0x4C4A27: sqlite3BtreeDelete (sqlite3.c:58313)
==1205== by 0x4D8C1E: sqlite3VdbeExec (sqlite3.c:71654)
==1205== by 0x4D0924: sqlite3Step (sqlite3.c:66192)
==1205== by 0x4D0B28: sqlite3_step (sqlite3.c:66258)
==1205== Address 0x4cae77a is 986 bytes inside a block of size 1,280 alloc'd
==1205== at 0x4A069EE: malloc (vg_replace_malloc.c:270)
==1205== by 0x4A086C: sqlite3MemMalloc (sqlite3.c:16359)
==1205== by 0x4A1276: mallocWithAlarm (sqlite3.c:19730)
==1205== by 0x4A1311: sqlite3Malloc (sqlite3.c:19763)
==1205== by 0x4ADE35: pcache1Alloc (sqlite3.c:38393)
==1205== by 0x4ADFCF: pcache1AllocPage (sqlite3.c:38477)
==1205== by 0x4AEA16: pcache1Fetch (sqlite3.c:38985)
==1205== by 0x4AD38E: sqlite3PcacheFetch (sqlite3.c:37805)
==1205== by 0x4B4374: sqlite3PagerAcquire (sqlite3.c:45197)
==1205== by 0x4BBE66: btreeGetPage (sqlite3.c:52758)
==1205== by 0x4C143E: allocateBtreePage (sqlite3.c:56424)
==1205== by 0x4C4F57: btreeCreateTable (sqlite3.c:58509)
==1205==
==1205== Conditional jump or move depends on uninitialised value(s)
==1205== at 0x4D6490: sqlite3VdbeExec (sqlite3.c:70162)
==1205== by 0x4D0924: sqlite3Step (sqlite3.c:66192)
==1205== by 0x4D0B28: sqlite3_step (sqlite3.c:66258)
==1205== by 0x47E041: MyClass::MyFunction(...) (MyClass.cpp:722)
==1205==
==1205== Conditional jump or move depends on uninitialised value(s)
==1205== at 0x4D6605: sqlite3VdbeExec (sqlite3.c:70199)
==1205== by 0x4D0924: sqlite3Step (sqlite3.c:66192)
==1205== by 0x4D0B28: sqlite3_step (sqlite3.c:66258)
==1205== by 0x47E041: MyClass::MyFunction(...) (MyClass.cpp:722)
==1205==
==1205== Conditional jump or move depends on uninitialised value(s)
==1205== at 0x4CDFF4: sqlite3VdbeSerialType (sqlite3.c:64539)
==1205== by 0x4D640E: sqlite3VdbeExec (sqlite3.c:70149)
==1205== by 0x4D0924: sqlite3Step (sqlite3.c:66192)
==1205== by 0x4D0B28: sqlite3_step (sqlite3.c:66258)
==1205== by 0x47B8B3: MyClass::MyFunction(...) (MyClass.cpp:576)
==1205==
==1205== Conditional jump or move depends on uninitialised value(s)
==1205== at 0x4CDFF4: sqlite3VdbeSerialType (sqlite3.c:64539)
==1205== by 0x4D65F7: sqlite3VdbeExec (sqlite3.c:70198)
==1205== by 0x4D0924: sqlite3Step (sqlite3.c:66192)
==1205== by 0x4D0B28: sqlite3_step (sqlite3.c:66258)
==1205== by 0x47B8B3: MyClass::MyFunction(...) (MyClass.cpp:576)
==1205==
==1205== Conditional jump or move depends on uninitialised value(s)
==1205== at 0x4CE008: sqlite3VdbeSerialType (sqlite3.c:64540)
==1205== by 0x4D640E: sqlite3VdbeExec (sqlite3.c:70149)
==1205== by 0x4D0924: sqlite3Step (sqlite3.c:66192)
==1205== by 0x4D0B28: sqlite3_step (sqlite3.c:66258)
==1205== by 0x47B8B3: MyClass::MyFunction(...) (MyClass.cpp:576)
==1205==
==1205== Conditional jump or move depends on uninitialised value(s)
==1205== at 0x4CE019: sqlite3VdbeSerialType (sqlite3.c:64541)
==1205== by 0x4D640E: sqlite3VdbeExec (sqlite3.c:70149)
==1205== by 0x4D0924: sqlite3Step (sqlite3.c:66192)
==1205== by 0x4D0B28: sqlite3_step (sqlite3.c:66258)
==1205== by 0x47B8B3: MyClass::MyFunction(...) (MyClass.cpp:576)
==1205==
==1205== Conditional jump or move depends on uninitialised value(s)
==1205== at 0x4CE030: sqlite3VdbeSerialType (sqlite3.c:64542)
==1205== by 0x4D640E: sqlite3VdbeExec (sqlite3.c:70149)
==1205== by 0x4D0924: sqlite3Step (sqlite3.c:66192)
==1205== by 0x4D0B28: sqlite3_step (sqlite3.c:66258)
==1205== by 0x47B8B3: MyClass::MyFunction(...) (MyClass.cpp:576)
==1205==
==1205== Conditional jump or move depends on uninitialised value(s)
==1205== at 0x4CE008: sqlite3VdbeSerialType (sqlite3.c:64540)
==1205== by 0x4D65F7: sqlite3VdbeExec (sqlite3.c:70198)
==1205== by 0x4D0924: sqlite3Step (sqlite3.c:66192)
==1205== by 0x4D0B28: sqlite3_step (sqlite3.c:66258)
==1205== by 0x47B8B3: MyClass::MyFunction(...) (MyClass.cpp:576)
==1205==
==1205== Conditional jump or move depends on uninitialised value(s)
==1205== at 0x4CE019: sqlite3VdbeSerialType (sqlite3.c:64541)
==1205== by 0x4D65F7: sqlite3VdbeExec (sqlite3.c:70198)
==1205== by 0x4D0924: sqlite3Step (sqlite3.c:66192)
==1205== by 0x4D0B28: sqlite3_step (sqlite3.c:66258)
==1205== by 0x47B8B3: MyClass::MyFunction(...) (MyClass.cpp:576)
==1205==
==1205== Conditional jump or move depends on uninitialised value(s)
==1205== at 0x4CE030: sqlite3VdbeSerialType (sqlite3.c:64542)
==1205== by 0x4D65F7: sqlite3VdbeExec (sqlite3.c:70198)
==1205== by 0x4D0924: sqlite3Step (sqlite3.c:66192)
==1205== by 0x4D0B28: sqlite3_step (sqlite3.c:66258)
==1205== by 0x47B8B3: MyClass::MyFunction(...) (MyClass.cpp:576)
==1205==
==1205==
==1205== HEAP SUMMARY:
==1205== in use at exit: 6,976,167 bytes in 115,360 blocks
==1205== total heap usage: 3,276,840 allocs, 3,161,480 frees, 467,886,044 bytes allocated
当我检查gdb中的第一个错误时,条件跳转所基于的变量I似乎被初始化了:
(gdb) p pMem->u
$2 = {i = 0, nZero = 0, pDef = 0x0, pRowSet = 0x0, pFrame = 0x0}
所以我还是很困惑。下面是函数:
SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem *pMem, int file_format){
int flags = pMem->flags;
int n;
if( flags&MEM_Null ){
return 0;
}
if( flags&MEM_Int ){
/* Figure out whether to use 1, 2, 4, 6 or 8 bytes. */
# define MAX_6BYTE ((((i64)0x00008000)<<32)-1)
i64 i = pMem->u.i; <= i = 0
u64 u;
if( i<0 ){ <= line 64529
if( i<(-MAX_6BYTE) ) return 6;
/* Previous test prevents: u = -(-9223372036854775808) */
u = -i;
}else{
u = i;
}
if( u<=127 ){
return ((i&1)==i && file_format>=4) ? 8+(u32)u : 1;
}
if( u<=32767 ) return 2;
if( u<=8388607 ) return 3;
if( u<=2147483647 ) return 4;
if( u<=MAX_6BYTE ) return 5;
return 6;
}
if( flags&MEM_Real ){
return 7;
}
assert( pMem->db->mallocFailed || flags&(MEM_Str|MEM_Blob) );
n = pMem->n;
if( flags & MEM_Zero ){
n += pMem->u.nZero;
}
assert( n>=0 );
return ((n*2) + 12 + ((flags&MEM_Str)!=0));
}
我来回答我自己的问题。浏览(再次)一些类似的问题在Stackoverflow我发现,你可以使用选项--track-origins=yes
与Valgrind跟踪未初始化值的起源。使用这个选项,我从Valgrind得到了这个新的输出:
Uninitialised value was created by a heap allocation
==6050== at 0x4A075BC: operator new(unsigned long) (vg_replace_malloc.c:298)
==6050== by 0x458AC2: MyOtherClass::MyOtherFunction(...) (MyOtherClass.cpp:378)
通过进一步调查,我发现在绑定了一些变量的数据类型中有两个unsigned long类型,它们没有在构造函数中初始化。然而,这些变量是在之后设置的,这种类型的对象使用new创建到堆中。从来没有真正使用未初始化值的情况,这使得很难发现问题在哪里。
- 是否可以初始化不可复制类型的成员变量(或基类)
- C++使用整数的压缩数组初始化对象
- C++初始化基类
- 多成员Constexpr结构初始化
- 复制列表初始化的隐式转换的等级是多少
- 内联映射初始化的动态atexit析构函数崩溃
- 如何在C++中初始化嵌套类中的2个memeber
- 如何声明特征矩阵,然后通过嵌套循环初始化它
- 没有用于初始化C++中的变量模板的匹配构造函数
- 在未初始化映射的情况下,将值插入到映射的映射中
- C++成员初始化
- 为什么在C++中首先初始化成员类
- 同时具有"聚合初始化"和"模板推导"
- 初始化具有非默认构造函数的std::数组项的更好方法
- 是否可以在编译时初始化数组,以便在运行时不会花费时间?
- 我可以使用条件运算符初始化C风格的字符串文字吗
- 在C和C++中初始化结构中的数组
- 标准是否使用多余的大括号(例如 T{{{10}}})定义列表初始化?
- 在函数内部的声明中初始化数组,并在外部使用它
- 继承:构造函数,初始化C++11中基类的类C数组成员