使用 Arrow 调试代码#
Arrow C++ 的 GDB 扩展#
默认情况下,当要求打印 C++ 对象的值时,GDB 会显示其成员变量的内容。但是,对于 C++ 对象来说,这通常不会产生非常有用的输出,因为 C++ 类倾向于将其实现细节隐藏在方法和访问器后面。
例如,以下是 GDB 可能显示 arrow::Status
实例的方式
$3 = {
<arrow::util::EqualityComparable<arrow::Status>> = {<No data fields>},
<arrow::util::ToStringOstreamable<arrow::Status>> = {<No data fields>},
members of arrow::Status:
state_ = 0x0
}
$4 = (arrow::Decimal128Scalar) {
<arrow::DecimalScalar<arrow::Decimal128Type, arrow::Decimal128>> = {
<arrow::internal::PrimitiveScalarBase> = {
<arrow::Scalar> = {
<arrow::util::EqualityComparable<arrow::Scalar>> = {<No data fields>},
members of arrow::Scalar:
_vptr.Scalar = 0x7ffff6870e78 <vtable for arrow::Decimal128Scalar+16>,
type = std::shared_ptr<arrow::DataType> (use count 1, weak count 0) = {
get() = 0x555555ce58a0
},
is_valid = true
}, <No data fields>},
members of arrow::DecimalScalar<arrow::Decimal128Type, arrow::Decimal128>:
value = {
<arrow::BasicDecimal128> = {
<arrow::GenericBasicDecimal<arrow::BasicDecimal128, 128, 2>> = {
static kHighWordIndex = <optimized out>,
static kBitWidth = 128,
static kByteWidth = 16,
static LittleEndianArray = <optimized out>,
array_ = {
_M_elems = {[0] = 1234567, [1] = 0}
}
},
members of arrow::BasicDecimal128:
static kMaxPrecision = 38,
static kMaxScale = 38
}, <No data fields>}
}, <No data fields>}
幸运的是,GDB 还允许自定义扩展覆盖特定类型的默认打印。我们提供了一个用 Python 编写的 GDB 扩展,它可以为常见的 Arrow C++ 类启用漂亮的打印,从而实现更高效的调试体验。例如,以下是前面提到的 arrow::Status
实例的显示方式
$5 = arrow::Status::OK()
以及与上面相同的 arrow::Decimal128Scalar
实例
$6 = arrow::Decimal128Scalar of value 123.4567 [precision=10, scale=4]
手动加载#
要启用 Arrow 的 GDB 扩展,您只需将其 下载 到您计算机上的某个位置,然后从 GDB 提示符下 source
它
(gdb) source path/to/gdb_arrow.py
您必须在每个新的 GDB 会话中对其进行 source
操作。您可能希望通过在 gdbinit 文件中添加 source
调用使其成为隐式操作。
自动加载#
GDB 提供了一种工具,可以为调试会话中涉及的每个目标文件或库自动加载脚本或扩展。您需要
找出 GDB 安装的*自动加载*位置。这可以使用 GDB 提示符上的
show
子命令来确定;答案将取决于操作系统。以下是 Ubuntu 上的示例
(gdb) show auto-load scripts-directory List of directories from which to load auto-loaded scripts is $debugdir:$datadir/auto-load. (gdb) show data-directory GDB's data directory is "/usr/share/gdb". (gdb) show debug-file-directory The directory where separate debug symbols are searched for is "/usr/lib/debug".
这告诉您用于自动加载的目录是
$debugdir
和$datadir/auto-load
,它们分别扩展为/usr/lib/debug/
和/usr/share/gdb/auto-load
。找出 Arrow C++ DLL 的完整路径,*所有符号链接都已解析*。例如,您可能已将 Arrow 7.0 安装在
/usr/local
中,则 Arrow C++ DLL 的路径可能是/usr/local/lib/libarrow.so.700.0.0
。确定实际的自动加载脚本路径。它的计算方法是:*a)* 获取您选择的自动加载目录的路径,*b)* 追加 Arrow C++ DLL 的完整路径,*c)* 在尾部追加
-gdb.py
。在上面的示例中,如果我们选择
/usr/share/gdb/auto-load
作为自动加载目录,则自动加载脚本的完整路径必须是/usr/share/gdb/auto-load/usr/local/lib/libarrow.so.700.0.0-gdb.py
。将 GDB 扩展 复制或符号链接到步骤 3 中确定的文件路径。
如果一切顺利,那么 sobald GDB 遇到 Arrow C++ DLL 时,它将自动加载 Arrow GDB 扩展,以便在显示提示符上漂亮地打印 Arrow C++ 类。
支持的类#
Arrow GDB 扩展为核心的 Arrow C++ 类提供漂亮的打印
arrow::DataType
及其子类arrow::Scalar
及其子类
重要的实用程序类也包括在内