Is there a way to print an Armadillo matrix in gdb?

前端 未结 5 1386
天命终不由人
天命终不由人 2020-12-11 03:41

I\'m using gdb to debug my c++ program. I\'m using the armadillo numerical library to define my matrices. I have an armadillo matrix defined like so:

mat A =         


        
相关标签:
5条回答
  • 2020-12-11 04:23

    The question may be old, but stumbling over it made me find a solution for my own work.

    Due to the template-based nature of the Armadillo library you need to provide some helpers of your own:

    #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;
    }
    

    Now you can easily call print_matrix from within 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
    

    Thanks to tab completion you only need to actually type a few characters of print_matrix<arma::Mat<double> >.

    0 讨论(0)
  • 2020-12-11 04:27

    The best option is using gdb's python API to create pretty printers for the armadillo classes. It works better than calling a C/C++ function, since it is always accessible (even when debugging from a core file where there is no program running). Furthermore, there is no risk of the linker discarding the function when it is not used in your program (thus making it unavailable when you are debugging in gdb).

    The pretty printer code is loaded (sourced) from the .gdbinit file in your home folder. It will work in gdb running in a terminal as well as from an IDE (assuming the IDE does not avoid loading the .gdbinit file).

    As an example, suppose you have the following two matrices

    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}};
    

    A pretty printer might shown them as

    Notice how the complex matrix m2 has its elements displayed both in rectangular form as well as in polar form (displaying the polar form can be disabled). This also works better with the rest of gdb. For instance, gdb allows you to the maximum number of elements to show in an array. The pretty printer will respect that if it is implemented to display the elements as standard arrays in gdb.


    This is how the m1 and m2 matrices are displayed in CLion.


    This pretty printer can be obtained from here. There are a few other things such as some xmethods (python re-implementation of some C++ methods) and conversion to numpy arrays.

    Disclaimer: I'm the author of these pretty printers.

    0 讨论(0)
  • 2020-12-11 04:27

    For those using QtCreator, you can inspect the values from your IDE by extending GDB with Python Debugging Helpers (maybe other IDEs support this feature too).

    Place the following script in, for example, ~/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
    

    And call it adding this line to your ~/.gdbinit:

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

    or add it from your IDE; in QtCreator use Tools > Options > Debugger > GDB (tab) > Extra Debugging Helpers (near the bottom).

    This particular script will return the matrix arranged by columns (natural memory arrangement in my architecture):

    enter image description here

    Sources: Writing Debug Visualizers for GDB / QtCreator 2.8

    0 讨论(0)
  • 2020-12-11 04:31

    You can call C functions in gdb, so you just need a function that prints your objects. E.g:

    (gdb) call printf("%.2f", 3.1428)
    $7 = 4
    (gdb) call fflush(stdout)
    3.14$8 = 0
    
    0 讨论(0)
  • 2020-12-11 04:34

    The simplest way is to print directly in gdb, unfortunately no fancy format

    > 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}}
    
    0 讨论(0)
提交回复
热议问题