通过GDB打印blitz阵列

printing blitz arrays via GDB

本文关键字:阵列 blitz 打印 GDB 通过      更新时间:2024-05-23

我最近几天一直在使用Blitz数组包。在调试期间,我需要打印数组内容,blitz支持下面的

std::cout<<blitz_array_name<<std::endl

我想在调试期间通过GDB打印数组内容。因此,我为不同类型的数组编写了重载函数,我喜欢使用这些函数,比如下面的函数

void printBlitz(blitz::Array<bool, 1> &in)
{
std::cout<<in<<std::endl;
}
void printBlitz(blitz::Array<int, 1> &in)
{
std::cout<<in<<std::endl;
}
... and so on

在gdb调试器上,我可以简单地调用下面的函数

(gdb) call printBlitz(blitz_array_name)
  1. 现在的问题是我正在使用许多类型的多维数组,我必须为每个数组进行重载
  2. 我无法通过GDB的调用功能调用模板函数-这也会有所帮助
  3. 我试着做下面这样的事情

(gdb(定义printmyvarcall(void(运算符<lt;(std::cout,$arg0(打印"\n"结束

当我尝试将数组打印为以下时

(gdb) printmyvar blitz_array_name

我得到这个错误"无法将函数运算符<<解析为任何重载实例">

d( 我可以将宏定义为以下

PRINTBLITZ(myvar) std::cout<<myvar<<std::endl

但是通过GDB,我不能传递宏并执行它。

我们如何简单地从GDB执行以下内容

std::cout<<myvar<<std::endl

请对此问题提出任何解决方案。非常感谢任何建议,并加快我的调试。

提前非常感谢!!

  1. 我无法通过GDB的调用功能调用模板函数-这也会有所帮助

实际上,在尝试了一些替代方案后,似乎可以,但很难正确地点出它。

考虑以下代码

#include <iostream>
double tripleInput(double x) { return 3 * x; }
template <typename T>
inline T doubleInput(T x) {
return 2 * x;
}

int main(int argc, char *argv[])
{
std::cout << doubleInput(13) << std::endl;
std::cout << doubleInput(1.72) << std::endl;
std::cout << tripleInput(1.72) << std::endl;
return 0;
}

在用调试符号编译并用可执行文件启动gdb之后,我们可以进行

call tripleInput(1.5)

gdb将返回4.5。到目前为止还不错。但是,请注意,如果您编写call tri并按TAB,gdb将以tripleInput(double)的形式完成名称。之后添加(1.5),就可以作为运行

tripleInput(double)(1.5)

这将像以前一样工作。

现在让我们尝试使用模板化的doubleInput函数。这是模板的名称,但只有当您将模板与某种类型一起使用时,编译器才会从模板生成函数。实际名称为doubleInput<int>doubleInput<double>等。只有您实际使用过的版本才会在二进制文件中,并且gdb可以看到。

现在让我们试试

call doubleInput<double>(1.7)

gdb返回CCD_ 7。太棒了注意

call doubleInput<double>(double)(1.7)

同样有效。只是要注意

call doubleInput<int>(1.7)

返回2,而不是3.3999999999999999,但这是有道理的。

因此,答案是,只要传递全名(使用TAB键完成名称(,就可以调用模板的实例。

最后要注意的是,如果我将tripleInput和doubleInput更改为通过引用而不是通过值接收参数,那么它将不起作用,并且我会得到错误"尝试获取不在内存中的值的地址"。


  1. 现在的问题是我正在使用许多类型的多维数组,我必须为每个数组进行重载

对于前面的答案,这意味着您可以编写单个模板,而不是多个实现。一定要打一次电话。即使您确实实现了几个函数,您仍然需要调用它们,以便链接器不会将其从二进制文件中删除。


但为了帮助调试,到目前为止,最好的解决方案是使用gdb的Python API为bliz::Array类型编写定制的漂亮打印机。如果你有漂亮的blitz类型的打印机,而你只需要看到blitz::Array就是p variable_name。即使从核心文件进行调试,这也始终有效(如果没有较差的运行,就无法调用函数(。

不幸的是,我找不到任何用于blitz的漂亮打印机的现有实现,这意味着你必须自己编写它。

我没有闪电战的经验,但我经常使用armadillo,这是一个用于线性代数的C++库;科学计算,我为armadillo类型写了漂亮的打印机。如果你很好奇,可以看看这个答案和这个存储库。

编写漂亮的打印机需要你稍微了解编写漂亮打印机的类型存储数据的方式。您需要阅读gdb的相关文档,但最好的方法是查看漂亮打印机的其他实现。至少我是这么做的。