使用 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
}
这里是一个 arrow::Decimal128Scalar
$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 的完整路径,并解析所有符号链接。例如,您可能已在
/usr/local
中安装了 Arrow 7.0,然后 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 中确定的文件路径。
如果一切顺利,那么当 GDB 遇到 Arrow C++ DLL 时,它将自动加载 Arrow GDB 扩展,以便在显示提示符上美观打印 Arrow C++ 类。
支持的类#
Arrow GDB 扩展为核心 Arrow C++ 类提供美观打印
arrow::DataType
和子类arrow::Scalar
和子类
还涵盖了重要的实用程序类