Hi there,
just got myself the source code of codeblocks and would like to enhance the debugger plugin a little. Basically what I need is efficient array/vector debugging. Right now the debugger already supports debugging of c-arrays and vectors, but sometimes fails for no apparent reason.
Starting with c-arrays, here are a few examples:
double arr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
double * arr_ptr = arr;
Debugger shows when watching arr:
arr
|- 1
|- 2
|- 3
|- 4
|- 5
|- 6
|- 7
|- 8
|- 9
|- 10
However, it does not show the array indices (which would be very useful when inspecting large arrays). Suggested format would be
either:
arr = 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
or
arr
[0] = 1
[1] = 2
[2] = 3
[3] = 4
[4] = 5
[5] = 6
[6] = 7
[7] = 8
[8] = 9
[9] = 10
It would be nice if the debugger would support both formats. When I'm debugging several arrays and I need a quick comparison on the content of two arrays, the 'single line' format is more useful. Related to that I would like to specify the output format for the doubles, e.g. scientific, precision=3, or fixed, precision=2.
When inspecting arr_ptr, the debugger fails to show the content as array, regardless if I inspect arr_ptr[0] or *arr_ptr with any number for 'count'.
However, gdb shows the content correctly for
output /f arr_ptr[0]@10
Range indices start and count do not work with c-arrays yet.
I would like to start enhancing the debugger plugin by implementing proper support for c-arrays. Now, before hacking the source code I would like to have some feedback on my proposed changes/additions, because I'm really new to the CodeBlocks source code and may overlook some design issues.
1. for all pointer types, if count != 0, add the debugger command
output \<flag> <ptr>[start]@count
2. for array output, improve parsing debugger output and create two alternative watch outputs:
arr = [1, 2, 3, 4]
and
arr
[start+0] = ...
[start+1] = ...
[start+2] = ...
...
[start+count-1] = ...
The format can be selected as boolean from the Edit Watch dialog (becomes a new member variable in the Watch class)
3. Improve output parsing, so when debugger returns <repeats 42 times>, alter output to show
arr
[ 0] = 0
[ 1] = 1 <repeats 42 times>
[43] = 2
...
I will try to get this correctly working with c-arrays for various types first.
Would you have some suggestions on how to achieve this best?
Bye,
Andreas
Nice ideas but you 've only been talking about the simplest of cases. What if the array contains structures (or pointers to them)? How would it display them on a single line?
QuoteWhat if the array contains structures (or pointers to them)? How would it display them on a single line?
Indeed, for structures the display in a single line would be quite useless. And IMHO any attempt to write a somewhat smart code to distinguish between simple and complex cases would result in excessive parsing code, slow debugger expression evaluation and an unforseeable mess of rules and exceptions.
So, my proposal would be to add a flag in the debugger dialog that turns the automatic parsing of debugger output off. So if I inspect an array and turn parsing off, GDB would simply return:
arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
Which is pretty much my suggested line format. This flag could also be useful in cases, where the automatic parsing of the debugger output may cause undesired results and one wishes to preserve the raw output.
I'll submit a patch with this change and if you like it, we could add it as first step towards the debugging improvement.
Bye,
Andreas
About array index printing:
As I see from the source code, the current parsing algorithm works recursive based on the braces { }, inside the ParseEntry function however, it is not possible to deduce the actual array index used.
One solution would be to add an index variable as argument to ParseEntry, which can be used to compose the array index. It would have to be passed as reference, so that the parse entry function can manipulate it correctly, when it encounters a GDB output with format:
0 <repeats 400 times>
void DebuggerTree::ParseEntry(WatchTreeEntry& entry, Watch* watch, wxString& text, int& index)
{
int local_count = 0; // used for all subentries of this parsed text
int repeat_count = 1;
// parse text and check if 'repeats x times' text is included
// and set repeat_count appropriately
repeat_count = 400;
// do the other stuff
// parse subentries
ParseEntry(*newchild, watch, text, local_index); // proceed one level deeper
// before returning from function, advance index
index += repeat_count;
}
Problems with this approach:
Now we can print array indices, but how do we know that we actually monitor an index? If we blindly put array indices in front of everything that the debugger returns, we will get funny stuff like:
"Local Variables"
- - arr
[1] - arr2
Which is not what we want :-)
Right now I don't see a good solution to the whole debugger output parsing problem. Any ideas?
Andreas
Check tonight's nightly.
Awesome, nice job! I have to check the source to see how you did it...
Andreas
Is there any way to add a watch for a pointer that points to a dynamically allocated array in C?
Quote from: Poobah on January 12, 2007, 07:08:33 AM
Is there any way to add a watch for a pointer that points to a dynamically allocated array in C?
Add a watch to
*your_pointer.
Thanks. :)
Actually, that doesn't seem to work. It just dereferences the pointer, and disregards whatever you do with the array options.