Community
Participate
Working Groups
A pretty printer for code generated for protocol buffer messages prints the names of the protocol message fields, which are not identical to the names of the class members in the generated C++ code. For example, a protocol message field called "d" is represented by a class data member called "d_". This confuses the hell out of CDT debug code, which tries to access the member called "d" and fails: 732,408 109-var-list-children var3 1 101 732,409 109^done,numchild="0",has_more="0" 732,409 (gdb) 732,409 110-var-set-update-range var3 0 101 732,409 110^done 732,409 (gdb) 732,444 111-var-create --thread 1 --frame 0 - * &((all_types).[d]) 732,444 111^error,msg="-var-create: unable to create variable object"
See related GDB issue https://sourceware.org/bugzilla/show_bug.cgi?id=17529
Can you provide a slightly more detailed example, I'm not quite understanding which names we get and shouldn't use. My first reaction is that we follow what GDB provides, but looking at the description on the GDB bug, maybe we look at fields we should not or something. The example will help.
The problem, as I understand it, is that var-list-children command returns names of class fields generated by the pretty printer. If these names don't match the true names of the class fields, a subsequent attempt to display the nonexistent fields using var-create command fails. Does CDT use field names returned by var-list-children in the Variables view? If so, we have a dilemma since the pretty-printed names are most suitable for display, but the original names are required to access the field values. It looks like we need both kinds of names, but I'm not sure if it is possible to get them from GDB.
(In reply to Sergey Prigogin from comment #3) > The problem, as I understand it, is that var-list-children command returns > names of class fields generated by the pretty printer. If these names don't > match the true names of the class fields, a subsequent attempt to display > the nonexistent fields using var-create command fails. > > Does CDT use field names returned by var-list-children in the Variables > view? If so, we have a dilemma since the pretty-printed names are most > suitable for display, but the original names are required to access the > field values. It looks like we need both kinds of names, but I'm not sure if > it is possible to get them from GDB. Sergey, your interpretation is right. You cannot, in general, apply -var-create to children of so-called dynamic varobjs. CDT tracks which varobjs are dynamic and reacts appropriately. For instance, the detail formatter will show a not-available message for children of dynamic varobjs, because there is no way to obtain something more useful for them. Furthermore, MIVariableObject's that are swapped out of the LRU cache and are a child of a dynamic varobj, cannot be re-created by the standard approach of calling -var-create. For that we track the index of a child within it's parent and then use -var-list-children again. See MIVariableObject#exprInfo and its usage for details. Having said this, what action triggered the -var-create on &((all_types).[d])? It possible should be adapted or handle the error appropriately.
Created attachment 248337 [details] A screenshot of the Variables showing the error
(In reply to Jens Elmenthaler from comment #4) Here is some more context: The attached screenshot of the Variables view corresponds to the following program stopped at breakpont on the return statement: int main() { M2 m; m.mutable_b()->set_a(5); return m.b().a(); } M2 is defined essentially as: class M1 { public: inline int32 a() const; inline void set_a(int32 value); private: int32 a_; }; class M2 { public: inline const M1& b() const; inline M1* mutable_b(); private: M1* b_; }; Both M1 and M2 have pretty printers. Here is a relevant piece of the gdb trace: 319,400 (gdb) 319,432 35-thread-info 1 319,433 35^done,threads=[{id="1",target-id="Thread 0x7ffff7ff39c0 (LWP 6308)",name="test",frame={lev\ el="0",addr="0x000000000040c422",func="main",args=[],file="test.cc",line="6"},state="stopped",core="\ 0"}] 319,433 (gdb) 319,962 36-stack-list-locals --thread 1 --frame 0 1 320,956 36^done,locals=[{name="m",value="Proto2Message = {[b] = Proto2Message = {[a] = 5}}"}] 320,956 (gdb) 320,980 37-stack-info-depth --thread 1 320,980 37^done,depth="1" 320,980 (gdb) 320,987 38-var-create --thread 1 --frame 0 - * m 320,989 38^done,name="var1",numchild="0",value="{...}",type="M2",thread-id="1",dynamic="1",has_more=\ "1" 320,989 (gdb) 321,268 39-var-list-children var1 321,269 39^done,numchild="1",children=[child={name="var1.[b]",exp="[b]",numchild="25",type="char [25\ ]",thread-id="1"}],has_more="0" 321,270 (gdb) 328,924 40-var-create --thread 1 --frame 0 - * &((m).[b]) 328,924 40^error,msg="-var-create: unable to create variable object" 328,925 (gdb) > CDT tracks which varobjs are dynamic and reacts appropriately. For instance, > the detail formatter will show a not-available message for children of > dynamic varobjs, because there is no way to obtain something more useful for > them. Furthermore, MIVariableObject's that are swapped out of the LRU cache > and are a child of a dynamic varobj, cannot be re-created by the standard > approach of calling -var-create. For that we track the index of a child > within it's parent and then use -var-list-children again. See > MIVariableObject#exprInfo and its usage for details. This is a really bad news since it means that it will never be possible to examine contents of m.b_ in the Variables view. My hope is that through some changes in CDT and, possibly, GDB, it should be possible to make such use case to work. This bug and the related https://sourceware.org/bugzilla/show_bug.cgi?id=17529 were created to have a brainstorming discussion on the issue. > Having said this, what action triggered the -var-create on > &((all_types).[d])? It possible should be adapted or handle the error > appropriately. The existing code is definitely wrong, but simple refusal to issue -var-create would not make the situation much better.
(In reply to Sergey Prigogin from comment #6) > 321,268 39-var-list-children var1 > 321,269 > 39^done,numchild="1",children=[child={name="var1.[b]",exp="[b]", > numchild="25",type="char [25\ > ]",thread-id="1"}],has_more="0" > 321,270 (gdb) > 328,924 40-var-create --thread 1 --frame 0 - * &((m).[b]) > 328,924 40^error,msg="-var-create: unable to create variable object" I haven't looked deeply into this, but I wanted to mention that when we create a variable with & it is because we are trying to figure out its address for the address column. I don't believe failing this causes serious problems (or at least it should not). Maybe we should skip this address call for pretty-printed children (or maybe we already do and there is a bug in the logic). There must be other errors after this one no?
(In reply to Marc Khouzam from comment #7) > I haven't looked deeply into this, but I wanted to mention that when we > create a variable with & it is because we are trying to figure out its > address for the address column. I don't believe failing this causes serious > problems (or at least it should not). Maybe we should skip this address > call for pretty-printed children (or maybe we already do and there is a bug > in the logic). I would agree, if the error were shown in the address column. But here it appears in the value column (see screenshot), with exactly the expression shown in the log.