GDB: Printing Variables to File
GDB is a great tool for debugging C and C++ code. To inspect the value of a variable, one can simply use the print
command. However, when the variable is an array, and it’s too large to print, or when you need to examine it carefully with other tools, then you may want to save it to a local file for further examination. Here is my guide for doing just that.
Setting the Logging and Printing Options
First, a quick guide. Just run the following commands:
set max-value-size unlimited
set print elements 0
set print repeats 0
set pagination off
set logging file file_to_save_data
set logging on
Then, the output of the next print
command would be redirected to file_to_save_data
. Explanation for each command:
set max-value-size unlimited
: max-value-size controls how much memory the debugger is willing to allocate for each variable it prints, as to print it, GDB needs to copy the variable from the debugged program to it’s own memory. Default value is 64 KiB, so for larger arrays, the latter parts may be truncated if this is not set.set print elements 0
: Remove the limit of elements for GDB to print. See print setting for more detail.set print repeats 0
: By default, when the number of consecutive identical elements of an array exceeds a threshold, GDB prints the string “<repeats n times>”. This command turns off this feature. Also see print setting for more detail.set pagination off
: When outputting a lot of information, GDB automatically pauses to avoid overwhelming the user. pagination turns this off.set logging file file_to_save_data
: Self explanatory.set logging on
: Start saving the output to the local file. Note that for a change tologging
to become effective, you need toset logging off
and thenset logging on
.
There are also many more settings that you could make, most of which are in the print
section. Look it up if the output is not good enough.
How to Output Arrays
Imagine you have a pointer to array int* arr = new int [10];
. If you run print arr
, then GDB would output:
(int *) 0x55555556aeb0
its type and its address (virtual of course). To output it’s zeroth member, run print arr[0]
, just like you would in code. To print it in its entirety, you need to to specify the number of elements to print, as GDB would have no way of knowing it. Run:
print *arr@10
To print the first ten elements of the array. You can do pointer arithmetic on the arr
pointer, for example, to print the second element and third:
print *(arr+1)@2
You can also use a more convoluted way to do it:
print *(int(*) [10])arr
First it casts the pointer-to-int to pointer-to-array-of-int, then dereferences it. Of course, I think the above method is better. See this post for more options.
Outputting Device Data in cuda-gdb
cuda-gdb is an extension to GDB developed by Nvidia, for debugging CUDA code on actual hardware. It’s based on GDB, so most of GDB’s commands are supported. To print a pointer to variables in device memory, either global or shared, you need to add a little bit. To print the first 18 members of shared double* ptr
which points to somewhere in shared device memory, use:
print ptr[0]@18
Sometimes the variable is not declared with the __shared__
or __device__
directive (to interface with non-cuda code, for example), so you’d need to explicitly cast it:
print ((@shared double *)ptr)[0]@18
Global memory can be also printed in a similar way. All the logging to file and redirection works exactly the same as with GDB.