Arrow C++的GDB扩展
默认情况下,当要求打印C++对象的值时,GDB会显示其成员变量的内容。然而,对于C++对象,这通常不会产生非常有用的输出,因为C++类 tend倾向于将其实现细节隐藏在方法和访问器后面。
例如,下面是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 path/to/gdb_arrow.py
您必须在每个新的GDB会话中进行源代码。您可能希望通过在gdbinit文件中添加source调用来使其隐式化。
自动加载
GDB提供了一种为参与调试会话的每个对象文件或库自动加载脚本或扩展的方法。您需要:
1. 找出您的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".
2. 找出Arrow C++ DLL的全路径,所有符号链接都已解析。例如,您可能已经在/usr/local中安装了Arrow 7.0,然后Arrow C++ DLL的路径可能是/usr/local/lib/libarrow.so.700.0.0。
3. 确定实际的自动加载脚本路径。它是由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。
4. 将GDB扩展复制或创建符号链接到步骤3中确定的文件路径。
如果一切顺利,那么只要GDB遇到Arrow C++ DLL,它将自动加载Arrow GDB扩展,以便在显示提示中漂亮地打印Arrow C++类。
支持的类
Arrow GDB扩展提供了核心Arrow C++类的漂亮打印:
arrow::DataType和其子类
arrow::Field、arrow::Schema和arrow::KeyValueMetadata
arrow::ArrayData、arrow::Array和其子类
arrow::Scalar和其子类
arrow::ChunkedArray、arrow::RecordBatch和arrow::Table
arrow::Datum
重要的实用类也已覆盖:
arrow::Status和arrow::Result
arrow::Buffer和其子类
arrow::Decimal128和arrow::Decimal256。