| Summary: | Variable view can show incorrect information for two variables with the same name and different scopes | ||||||
|---|---|---|---|---|---|---|---|
| Product: | [Tools] CDT | Reporter: | Phil Mason <pmason> | ||||
| Component: | cdt-debug-dsf | Assignee: | Project Inbox <cdt-debug-dsf-inbox> | ||||
| Status: | NEW --- | QA Contact: | Jonah Graham <jonah> | ||||
| Severity: | minor | ||||||
| Priority: | P3 | CC: | branko.drevensek, cdtdoug, jason.litton, marc.khouzam | ||||
| Version: | 8.0 | ||||||
| Target Milestone: | --- | ||||||
| Hardware: | PC | ||||||
| OS: | Linux | ||||||
| Whiteboard: | |||||||
| Attachments: |
|
||||||
|
Description
Phil Mason
This code demonstrates the problem
#include <stdio.h>
#include <stdlib.h>
void passPtrTest (int * foo, int bar);
int main(void) {
int tmp = 5;
int tmp2 = 13;
passPtrTest(&tmp, tmp2);
return EXIT_SUCCESS;
}
void passPtrTest (int * foo, int bar)
{
int i;
int outerFoo;
int *ptrOuterFoo = &outerFoo;
*foo = 7;
for(i=0; i<5; i++)
{
int bar = 7;
int * foo = &outerFoo;
*foo = i +bar;
}
printf("The value of ptrOuterTester is %d\n", *ptrOuterFoo);
}
This is related to Bug 210976, except that in your case one variable is an argument while the other is a local variable. If I remember correctly, the problem is that I don't know of a way for us to tell GDB which of the two foo variable we want to access. For example, if you go to the gdb console during your test, how would you ask GDB to print the value of the first foo variable? Sorry, I didn't find the earlier bug when googling. I agree that they are related. Consider the following example:
1 #include <stdio.h>
2 #include <stdlib.h>
3 int main(void)
4 {
5 int foo = 7;
6 if(foo > 6)
7 {
8 int foo = 9;
9 printf("foo = %d",foo);
10 }
11 return EXIT_SUCCESS;
12 }
If you look at the variable view in Eclipse when stopped at line 6 it shows that foo = 7 (which is correct) stepping forward twice (now stopped on 9) it still shows foo = 7 (which is definitely not correct). I think that it is possible to tweak what is sent to GDB to prevent the variable view silently reporting incorrect values.
The Eclipse UI doesn't update because the MI variable object doesn't change value as you enter the new scope. If floating variable objects were used then calling -var-update would update the variable object to the correct value as the scope changed. For example, given the above code, at the end of this comment is a (somewhat cut down) GDB trace showing this in working.
I think that this would be an improvement on the current behaviour as, whilst the meaning of a name might change with no visual clue, at least the GUI wouldn't report incorrect information. I've had a quick look around and I can't see any discussion of this possible solution, apologies if I've missed it or there is an obvious reason why it wouldn't work.
GDB sample run below (using GDB 7.2)
bash:pmason:xl-cbga-20:57> gdb --interpreter=mi minimal-flashing
(gdb) l
&"l\n"
~"1\t#include <stdio.h>\n"
~"2\t#include <stdlib.h>\n"
~"3\tint main(void)\n"
~"4\t{\n"
~"5\t int foo = 7;\n"
~"6\t if(foo > 6)\n"
~"7\t {\n"
~"8\t int foo = 9;\n"
~"9\t printf(\"foo = %d\",foo);\n"
~"10\t }\n"
^done
(gdb) b 6
(gdb) run
~"\nBreakpoint "
~"1, main () at ../src/minimal-flashing.c:6\n"
(gdb) -var-create myfoo @ foo
^done,name="myfoo",numchild="0",value="7",type="int",thread-id="1",has_more="0"
(gdb) -var-evaluate-expression myfoo
^done,value="7"
(gdb) step
~"8\t int foo = 9;\n"
(gdb) -var-update 1 *
^done,changelist=[{name="myfoo",value="0",in_scope="true",type_changed="false",has_more="0"}]
(gdb) step
~"9\t printf(\"foo = %d\",foo);\n"
(gdb) -var-update 1 *
^done,changelist=[{name="myfoo",value="9",in_scope="true",type_changed="false",has_more="0"}]
(gdb) step
~"11\t\treturn EXIT_SUCCESS;\n"
(gdb) -var-update 1 *
^done,changelist=[{name="myfoo",value="7",in_scope="true",type_changed="false",has_more="0"}]
Created attachment 210269 [details]
Patches DSF to use floating frames for variables
Given this code:
1 #include <stdio.h>
2 #include <stdlib.h>
3 int main(void)
4 {
5 int foo = 7;
6 if(foo > 6)
7 {
8 int foo = 9;
9 printf("foo = %d",foo);
10 }
11 return EXIT_SUCCESS;
12 }
The patch makes the variable view display the correct value for foo when single stepping through the code (in DSF launches).
The the fix doesn't seem to work on older versions of GDB (I tried it on 6.8) but then the behaviour is simply the same as the previous behaviour (the view doesn't update when the scope changes) so the patch shouldn't make anything worse.
Just a note that this bug is similar to bug 327621 bug 328573 bug 210976 *** Bug 371014 has been marked as a duplicate of this bug. *** So this is still present on Kepler SR1? This is what got me scratching my head.
---
int subroutine1()
{
static int a = 0;
return a++;
}
int subroutine2()
{
static int a = 7;
return a++;
}
int main()
{
return subroutine1() + subroutine2() + subroutine2();
}
---
When stepping through this code, variable a stays at 1 the whole time.
(In reply to Branko Drevensek from comment #7) > So this is still present on Kepler SR1? This is what got me scratching my > head. > --- > int subroutine1() > { > static int a = 0; > return a++; > } > int subroutine2() > { > static int a = 7; > return a++; > } > int main() > { > return subroutine1() + subroutine2() + subroutine2(); > } > --- > When stepping through this code, variable a stays at 1 the whole time. This is because of the 'static' keyword. For some reason, when stepping into subroutine2, gdb says variable a of subroutine1 is still in scope: 053,593 71-var-update 1 var1 053,595 71^done,changelist=[{name="var1",value="1",in_scope="true",type_changed="false",has_more="0"\ }] so CDT thinks they are the same variable. My guess is that since the variables are static, they are both still there when in subroutine2(), but I'm not sure how to tell the debugger which one we are interested in. I don't know if you can access both using the C or C++. |