调试提示
以下是 SQLite 开发人员用来跟踪、检查和理解核心 SQLite 库行为的随机技术分类。
这些技术旨在帮助理解核心 SQLite 库本身,而不是仅使用 SQLite 的应用程序。
-
在命令行 shell上使用“.eqp full”选项
当您有一个正在调试或试图理解的 SQL 脚本时,使用“.eqp full”设置在命令行 shell中运行它通常很有用。当“.eqp”设置为 FULL 时,shell在实际运行该命令之前自动显示每个命令 的EXPLAIN和EXPLAIN QUERY PLAN输出。
为了增加可读性,还要设置“.echo on”以便输出包含原始 SQL 文本。
较新的“.eqp trace”命令执行“.eqp full”所做的一切,并且还打开VDBE 跟踪。
-
使用编译时选项启用调试功能。
建议的编译时选项包括:
- -DSQLITE_DEBUG
- -DSQLITE_ENABLE_EXPLAIN_COMMENTS
- -DSQLITE_ENABLE_TREETRACE
- -DSQLITE_ENABLE_WHERETRACE
-
从调试器调用 sqlite3ShowExpr() 和类似的。
当使用SQLITE_DEBUG编译时,SQLite 包含将各种内部抽象语法树结构打印为 ASCII 艺术图的例程。这在调试中非常有用,以便了解 SQLite 正在使用的变量。以下例程可用:
- void sqlite3ShowExpr(const Expr*);
- void sqlite3ShowExprList(const ExprList*);
- void sqlite3ShowIdList(const IdList*);
- void sqlite3ShowSrcList(const SrcList*);
- void sqlite3ShowSelect(const Select*);
- void sqlite3ShowWith(const With*);
- void sqlite3ShowUpsert(const Upsert*);
- void sqlite3ShowTrigger(const Trigger*);
- void sqlite3ShowTriggerList(const Trigger*);
- void sqlite3ShowTriggerStep(const TriggerStep*);
- void sqlite3ShowTriggerStepList(const TriggerStep*);
- void sqlite3ShowWindow(const Window*);
- void sqlite3ShowWinFunc(const Window*);
这些例程不是 API,可能会发生变化。它们仅供交互式调试使用。
-
test_addoptrace 上的断点
调试字节码生成器时,了解特定操作码的生成位置通常很有用。要轻松找到它,请在调试器中运行脚本。在“test_addoptrace”例程上设置断点。然后运行“PRAGMA vdbe_addoptrace=ON;” 然后是相关的 SQL 语句。每个操作码都将显示为附加到 VDBE 程序,断点将在之后立即触发。步进直到到达操作码,然后在堆栈中向后查看以查看它是在哪里以及如何生成的。
这仅在使用SQLITE_DEBUG编译时有效。
-
使用“.treetrace”和“.wheretrace”shell 命令
当命令行 shell 和核心 SQLite 库都使用SQLITE_DEBUG和 SQLITE_ENABLE_TREETRACE 以及 SQLITE_ENABLE_WHERETRACE 编译时,那么 shell 有两个命令用于打开代码生成器最复杂部分的调试工具——处理 SELECT 语句的逻辑和WHERE 子句,分别。“.treetrace”和“.wheretrace”命令每个都有一个可以用十六进制表示的数字参数。每个位打开调试的各个部分。通常使用值“0xfff”和“0xff”。使用参数“0”关闭所有跟踪输出。
-
使用“.breakpoint”shell 命令
CLI 中的“.breakpoint”命令除了调用名为“test_breakpoint()”的过程外什么都不做,这是一个空操作。
如果你有一个脚本并且你想在脚本中途的某个点开始调试,只需在 gdb(或你正在使用的任何调试器)中的 test_breakpoint() 函数上设置一个断点,并添加一个“.breakpoint”命令你想停下来的地方。当您到达第一个断点时,将任何其他断点设置为您需要的变量跟踪。
-
禁用后备内存分配器
在查找内存分配问题(内存泄漏、释放后使用错误、缓冲区溢出等)时,有时禁用 后备内存分配器然后在 valgrind 或 MSAN 或其他一些堆内存调试工具下运行测试很有用。后备内存分配器可以在启动时使用SQLITE_CONFIG_LOOKASIDE 接口禁用。如果使用“--lookaside 0 0”命令行选项启动, 命令行 shell将使用该接口禁用后备。
SQLITE_ENABLE_TREETRACE 和 SQLITE_ENABLE_WHERETRACE 选项未记录在编译时选项文档中,因为它们不受官方支持。它们所做的是激活命令行 shell 中的“.treetrace”和“.wheretrace”点命令,它们分别为为 SELECT 和 DML 语句以及 WHERE 子句生成代码的逻辑提供低级跟踪输出。