- Am not able to call template functions via GDB's call feature - this would also help
Actually, after trying a few alternatives it seems that you can, but it is hard to dot it properly.
Consider the following code
#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;
}
After compiling with debug symbols and starting gdb with the executable we can do
call tripleInput(1.5)
and gdb will return 4.5. So far so good. Note however, that if you write call tri
and press TAB gdb will complete the name as tripleInput(double)
. After that you add (1.5)
and you can run as
tripleInput(double)(1.5)
which will work as before.
Now let's try with the templated doubleInput
function. That is the name of the template, but only once you use the template with some type is that the compiler will generate a function from the template. The actual names are doubleInput<int>
, doubleInput<double>
, etc. Only versions you have actually used will be in the binary and can be seen by gdb.
Now let's try
call doubleInput<double>(1.7)
and gdb returns 3.3999999999999999
. Great! Notice that
call doubleInput<double>(double)(1.7)
works as well. Just beware that
call doubleInput<int>(1.7)
returns 2, instead of 3.3999999999999999, but that makes sense.
So, the answer is that you can call instances of the template, as long as you pass the full name (use TAB to complete the name).
Just a final note, if I change the tripleInput and doubleInput to receive the argument by reference, instead of by value, then it won't work and I get the error "Attempt to take address of value not located in memory".
- The issue now is I am using many many types of multi-dimensional arrays, I have to make overloads for every array
With the previous answer, it means that you could write a single template instead of multiple implementations. Just be sure to call it once. Even if you do implement several functions, you still need to call them such that the linker does not remove it from the binary.
But in order to help debugging the best solution, by far, is using gdb's Python API to write custom pretty printers for bliz::Array
types. If you had pretty printers for blitz types and all you needed to see a blitz::Array
was p variable_name
. This would always work even if you are debugging from a core file (without an inferior running you can't call a function).
Unfortunately, I could not find any existing implementation of pretty printers for blitz, which means that you would have to write it yourself.
I don't have experience with blitz, but I often use armadillo, which is a C++ library for linear algebra & scientific computing, and I have written pretty printers for armadillo types. See this answer and this repository if you are curious.
Writing pretty printers requires you to understand a little about the way that the type you are writing pretty printers for stores its data. You will need to read gdb's documentation about it, but the best way is to look other implementations of pretty printers. At least that's how I've done it.