Valgrind报告sqlite3_step中未初始化的值

Valgrind reports uninitialised value(s) in sqlite3_step

本文关键字:初始化 step 报告 sqlite3 Valgrind      更新时间:2023-10-16

我正在编写一个多线程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创建到堆中。从来没有真正使用未初始化值的情况,这使得很难发现问题在哪里。