我正在尝试分析一个需要从 sqlite 数据库加载数据的程序。运行程序通常按预期运行,但是当我使用 callgrind 时,打开的数据库是空的(没有表;在数据库中设置的 user_version 返回为 0)。数据库文件在正确的路径中找到,并且似乎已正确打开,但其中没有任何内容。
测试程序(sqlite_test.cpp):
#include <sqlite3.h>
#include <iostream>
#include <sys/stat.h>
bool dbExists() {
struct stat s;
if (stat("testDB", &s) != 0) {
return false;
}
else {
return true;
}
}
int main()
{
if (dbExists())
std::cout << "db exists\n";
sqlite3 *db;
int open = sqlite3_open_v2("testDB", &db, SQLITE_OPEN_READWRITE, NULL);
if (open == SQLITE_OK) {
std::cout << "db opened\n";
}
else {
std::cout << "Failed to open DB; code: " << open << "\n";
}
sqlite3_stmt *stmt;
sqlite3_prepare_v2(db, "PRAGMA user_version;", -1, &stmt, NULL);
int dbVersion = 0;
int res = sqlite3_step(stmt);
if (res == SQLITE_ROW) {
dbVersion = sqlite3_column_int(stmt, 0);
}
else {
std::cout << "DB version not set: " << res << " " << sqlite3_errstr(res) << "\n";
}
std::cout << "Database version: " << dbVersion << std::endl;
sqlite3_close(db);
}
我创建了一个具有“pragma user_version = 5;”的数据库(“testDB”),并且与可执行文件位于同一文件夹中。可执行文件是使用
g++ sqlite_test.cpp -lsqlite3 -o sqlite_test
输出:
# ./sqlite_test
db exists
db opened
Database version: 5
# valgrind --tool=callgrind ./sqlite_test
==1184== Callgrind, a call-graph generating cache profiler
==1184== Copyright (C) 2002-2015, and GNU GPL'd, by Josef Weidendorfer et al.
==1184== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==1184== Command: ./sqlite_test
==1184==
==1184== For interactive control, run 'callgrind_control -h'.
db exists
db opened
Database version: 0
==1184==
==1184== Events : Ir
==1184== Collected : 2787290
==1184==
==1184== I refs: 2,787,290
我注意到的另一件事是,它在使用 valgrind (memcheck) 运行时似乎工作正常。只有 callgrind 才会出现问题。valgrind 3.12 和 3.14 都是如此。
更新:显然我应该提到我正在运行它,因为它似乎是问题的根源。我的问题是在单核 ARM 处理器上运行 Yocto 2.2.2 (Morty) 的系统上。如果我在运行 Ubuntu 18.04 的不同系统(即虚拟机)上运行相同的东西,则没有问题。我不确定这些系统之间的哪个差异导致了问题。