有没有办法在gdb中打印犰狳矩阵?

时间:2012-02-29 12:47:25

标签: c++ debugging matrix gdb armadillo

我正在使用gdb来调试我的c ++程序。 我正在使用犰狳数值库来定义我的矩阵。我有一个如此定义的犰狳矩阵:

mat A = randu<mat>(5,5);

使用gdb调试器时是否可以打印整个矩阵?

5 个答案:

答案 0 :(得分:8)

这个问题可能已经过时了,但对它的绊脚石让我找到了适合自己工作的解决方案。

由于Armadillo库的基于模板的特性,您需要提供一些自己的帮助:

#include <iostream>
#include <armadillo>

template<class Matrix>
void print_matrix(Matrix matrix) {
    matrix.print(std::cout);
}

//provide explicit instantiations of the template function for 
//every matrix type you use somewhere in your program.
template void print_matrix<arma::mat>(arma::mat matrix);
template void print_matrix<arma::cx_mat>(arma::cx_mat matrix);

int main() {
    arma::mat matrix = arma::randu(10,10);

    return 0;
}

现在,您可以在print_matrix内轻松致电gdb

(gdb) call print_matrix<arma::Mat<double> >(matrix) 
   0.8402   0.4774   0.0163   0.5129   0.5267   0.5260   0.2383   0.5316   0.6879   0.9565
   0.3944   0.6289   0.2429   0.8391   0.7699   0.0861   0.9706   0.0393   0.1660   0.5886
   0.7831   0.3648   0.1372   0.6126   0.4002   0.1922   0.9022   0.4376   0.4401   0.6573
   0.7984   0.5134   0.8042   0.2960   0.8915   0.6632   0.8509   0.9318   0.8801   0.8587
   0.9116   0.9522   0.1567   0.6376   0.2833   0.8902   0.2667   0.9308   0.8292   0.4396
   0.1976   0.9162   0.4009   0.5243   0.3525   0.3489   0.5398   0.7210   0.3303   0.9240
   0.3352   0.6357   0.1298   0.4936   0.8077   0.0642   0.3752   0.2843   0.2290   0.3984
   0.7682   0.7173   0.1088   0.9728   0.9190   0.0200   0.7602   0.7385   0.8934   0.8148
   0.2778   0.1416   0.9989   0.2925   0.0698   0.4577   0.5125   0.6400   0.3504   0.6842
   0.5540   0.6070   0.2183   0.7714   0.9493   0.0631   0.6677   0.3540   0.6867   0.9110

由于标签已完成,您只需要实际输入print_matrix<arma::Mat<double> >的几个字符。

答案 1 :(得分:2)

您可以在gdb中调用C函数,因此您只需要一个打印对象的函数。 E.g:

(gdb) call printf("%.2f", 3.1428)
$7 = 4
(gdb) call fflush(stdout)
3.14$8 = 0

答案 2 :(得分:1)

对于那些使用QtCreator 的人,您可以通过extending GDB with Python Debugging Helpers检查IDE中的值(也许其他IDE也支持此功能)。

将以下脚本放入,例如~/debugHelpers.py

#!/usr/bin/python

import gdb      # gdb.Value()
import dumper   # dumper.Children()

def qdump__arma__Mat(d, value):
    array = value["mem"]
    cols = value["n_cols"]
    rows = value["n_rows"]
    maxDisplayItems = 50
    innerType = d.templateArgument(value.type, 0)
    p = gdb.Value(array.cast(innerType.pointer()))
    d.putItemCount(cols)
    d.putNumChild(cols)
    if d.isExpanded():
        numDisplayItems = min(maxDisplayItems, cols)
        with dumper.Children(d, numChild=cols,
               maxNumChild=numDisplayItems,
               childType="<column>",
               addrBase=p,
               addrStep=p.dereference().__sizeof__):
            for i in range(0, int(numDisplayItems)):
                with dumper.Children(d):
                    d.putItemCount(rows)
                    d.putNumChild(rows)
                    if d.isExpanded():
                        numDisplayItems = min(maxDisplayItems, rows)
                        with dumper.Children(d, numChild=rows,
                               maxNumChild=numDisplayItems,
                               childType=innerType,
                               addrBase=p,
                               addrStep=p.dereference().__sizeof__):
                            for j in range(0, int(numDisplayItems)):
                                d.putSubItem(j, p.dereference())
                                p += 1

并将其添加到您的~/.gdbinit

python exec(open('/<full_path>/debugHelpers.py').read())

或从IDE添加;在QtCreator中使用工具&gt;选项&gt;调试器&gt; GDB(标签)&gt;额外的调试助手(靠近底部)。

这个特殊的脚本将返回按列排列的矩阵(我的架构中的自然内存排列):

enter image description here

资料来源:Writing Debug Visualizers for GDB / QtCreator 2.8

答案 3 :(得分:1)

最好的选择是使用gdb的python API为armadillo类创建pretty printers。它比调用C / C ++函数更好,因为它总是可访问的(即使在没有程序运行的核心文件中调试时)。此外,当程序中未使用该功能时,链接程序也不会丢弃该功能(因此,在gdb中进行调试时将使其不可用)。

漂亮的打印机代码是从您的主文件夹中的.gdbinit文件中加载的(来源)。它将在终端以及IDE中运行的gdb中运行(假设IDE不会避免加载.gdbinit文件)。

作为示例,假设您具有以下两个矩阵

arma::mat m1{{1.1, 2.2,  3},
             {  4,   5,  6}, 
             {  7,   8,  9},
             { 10,  11, 12},
             { 13,  14, 15},
             { 16,  17, 18}};

arma::cx_mat m2{{1.1 - 1.1j, 2.2 - 7.7j, 3},
                {         4,          5, 6},
                {         7,          8, 9},
                {         10,        11, 12},
                {         13,        14, 15},
                {         16,        17, 18}};

漂亮的打印机可能会将其显示为

m1

m2

请注意,复数矩阵m2的元素如何以矩形和极性形式显示(可以禁用显示极性形式)。这对于gdb的其余部分也更好。例如,gdb允许您最大数量的元素显示在数组中。漂亮的打印机如果实现了将元素显示为gdb中的标准数组的方式,则会对此予以尊重。


这是m1m2矩阵在CLion中的显示方式。

m1 in CLion

m2 in CLion


可以从here获得这款漂亮的打印机。还有其他一些事情,例如一些xmethods(某些C ++方法的python重新实现)和转换为numpy数组。

免责声明:我是这些漂亮打印机的作者。

答案 4 :(得分:0)

最简单的方法是直接在gdb打印,遗憾的是没有花哨的格式

> print *A.mem@5@5
$1 = {{0.84018771715470952, 0.39438292681909304,0.78309922375860586,0.79844003347607329, 0.91164735793678431},
{0.19755136929338396, 0.33522275571488902, 0.768229594811904, 0.27777471080318777, 0.55396995579543051}, 
{0.47739705186216025, 0.62887092476192441, 0.36478447279184334, 0.51340091019561551, 0.95222972517471283}, 
{0.91619506800370065, 0.63571172795990094, 0.71729692943268308, 0.14160255535580338, 0.60696887625705864}, 
{0.016300571624329581, 0.24288677062973696, 0.13723157678601872, 0.80417675422699042, 0.15667908925408455}}