The CLI "print" command shows user runtime type of C++ variable based on RTTI if "set print object" is "on". So gdb can show "real" type name for the objects that are stored by the interfaces and show their internals. Unfortunately, this information is not available via MI, so a lot of GUI tools that use it (like Eclipse CDT, Qt Creator, ...) cann't access it. Here is an example that demonstrates the case described above: struct Base { Base() : a(1) {} virtual ~Base() {} // Enforce type to have RTTI int a; }; struct Derived : public Base { Derived() : b(2) {} int b; }; int main() { Derived b; Base* aPtr = &b; return 0; // <= Set breakpoint here } Here is an example of CLI session: (gdb) p b $1 = (Derived) {<Base> = {_vptr.Base = 0x8048788, a = 1}, b = 2} (gdb) p *aPtr $2 = {_vptr.Base = 0x8048788, a = 1} (gdb) set print object on (gdb) p *aPtr $3 = (Derived) {<Base> = {_vptr.Base = 0x8048788, a = 1}, b = 2} Here is a fragment of MI session by Eclipse CDT ("set print object on" is done in .gdbinit): 782,149 (gdb) 782,149 23-var-create --thread 1 --frame 0 - * b 782,150 24-var-create --thread 1 --frame 0 - * aPtr 782,150 23^done,name="var1",numchild="2",value="{...}",type="Derived",thread-id="1",has_more="0" 782,150 (gdb) 782,150 24^done,name="var2",numchild="1",value="0xbffff428",type="Base *",thread-id="1",has_more="0"\ So can the "-var-create" command be extended to provide such information? Or maybe another command that will do it? Or the value of "type" field of "-var-create" command result will depend on "set print object"? Maybe the next bugs are connected to this one: Bug 9197 - Type printing uses different code from value access. Bug 9257 - set print object on does not work
*** Bug 10715 has been marked as a duplicate of this bug. ***
Qt Creator properly displays the "Derived" type in this case.
(In reply to comment #2) > Qt Creator properly displays the "Derived" type in this case. On what platform and for what debugger (AFAIK it supports gdb & cdb)? If gdb - can you clarify, how does it work? Does it use its own dumpers system?
Created attachment 6045 [details] Screenshot of Qt Creator display
Ok, I figured out that Qt Creator uses its own dumping system that relies on python interface to gdb. So it just use "dynamic_type" property of gdb value object. However, Eclipse CDT (and many other tools, I believe) uses standard MI interface. So I am wondering what is the preferable way to provide this information: - the "-var-create" command extension; - some another command creation; - "set print object" should affect MI interface; - some MI analogs of "set print object" command should be implemented;
I've been using the MI/varobj approach for quite some time (and unfortunately still have to on Mac) and it simply does not scale beyond simple scenarios like, say dumping a std::vector or std::map or such. For more complex displays it is far too inflexible and requires too many roundtrips translating directly into "waiting time" for the user. It's strictly no fun to work with, both from a frontend implementor's and an end user's perspective. An "all python" approach for data display is much more flexible, faster, and easier to extend for users. Also, gdb/MI in general has essentially been unmaintained for a more than year now (yes, I am aware of the added breakpoint notifications last April...), whereas gdb/Python has improved a lot in the meantime. So even assuming that the general MI/varobj approach would feasible in general (which I honestly doubt, e.g. the question which kind of data is "needed" in a response can never be answered in a frontend agnostic way and just spawned endless discussions with no tangible outcome in the past) I don't see evidence that gdb/MI could catch up to where gdb/Python already is in any interesting time frame. -- -- It's dead, Jim ;-|
(In reply to comment #5) > So I am wondering what is the preferable way to provide this information: [...] > - "set print object" should affect MI interface; I think this would be a natural approach.
Created attachment 6047 [details] proposed fixture Here is the proposed fixture of the problem.
Here are a few MI commands to reproduce the problem on example posted above: -interpreter-exec console "set print object on" -break-insert test_case.cpp:19 -exec-run -var-create v * *aPtr Actual behavior: type of varobj v is Base. Expected: type of varobj v is Derived.
I think this patch is probably necessary, but I am not certain that it is sufficient. E.g., why isn't create_child_with_value modified?
You are right. I have missed a few places. I'll try to provide a new patch soon.
Created attachment 6076 [details] Proposed fixture (see details in comment) Ok, finally I have researched this problem more carefully and I am ready to propose a new patch. However there are a few notes that I want to share: - currently gdb loses cv-qualifiers after RTTI type access. The simplest way to check it - make a print command on any "const Base*" value. It will be "Derived*" if "set print object" is on (by the way, Qt Creator loses it too). This patch fixes this problem for gdb MI&CLI (and maybe for Qt Creator too - a didn't check it) - whatis command does not work for C++ references. It prints an error instead of reference type. The proposed patch fixes this problem for gdb MI&CLI too (by the way, Qt Creator does not show a real type for references too, but I think this patch will not help it). - indirect pointers (I mean pointer to pointer or reference to pointer and so on) do not have a real type in whatis/print commands. The proposed patch does not fix this problem because there is another problem in gdb which does not allow to cast pointer to reference to pointer ("T*" => "T*&"). If it will be fixed it is quite easy to provide support of indirect references too (a few changes in value_rtti_target_type() should be enough). - the last unresolved problem is type update when value changed. I am not sure about how it should be done. Should we just set "type_changed" & "new_type" properties in the result of -var-update command? If so I think not all frontends will support it (at least Eclipse will not - I have checked it). Or maybe we should create dynamic varobj some how? Can somebody advice me something about it?
An extended example: #include <boost/shared_ptr.hpp> struct Base { Base() : a(1) {} virtual ~Base() {} // Enforce type to have RTTI int a; }; struct Derived : public Base { Derived() : b(2), c(3) {} int b; int c; }; struct S { Base* ptr; const Base* ptrConst; Base& ref; const Base& refConst; S(Derived& d) : ptr ( &d ) , ptrConst ( &d ) , ref ( d ) , refConst ( d ) {}; }; int main() { Derived d; S s(d); Base* ptr = &d; const Base* ptrConst = &d; Base& ref = d; const Base& refConst = d; Base** ptrToPtr = &ptr; // Interesting if pretty printer is used boost::shared_ptr<Base> sharedPtr (new Derived()); return 0; }
The dropping of "const" and "&" in the display in Qt Creator is intentional. Showing it (which had been possible in the past) is considered unhelpful noise with negligible benefit in fringe cases only. The "real" type is accessible through the main editor/F2 anyway. So if you can trigger a display of (toplevel) "const" or "&" for any output gdb (with or without your improvements) produces, please file a bug.
(In reply to comment #14) > The dropping of "const" and "&" in the display in Qt Creator is intentional. > Showing it (which had been possible in the past) is considered unhelpful noise > with negligible benefit in fringe cases only. The "real" type is accessible > through the main editor/F2 anyway. So if you can trigger a display of > (toplevel) "const" or "&" for any output gdb (with or without your > improvements) produces, please file a bug. Thanks for clarification. I did not check Qt Creator with gdb patched by me (because I cannot force it to use custom gdb), I have just made a few assumptions based on how it looks from inside. Maybe I am wrong. However, I don't think that "const" and "&" is unhelpful noise I can remove these changes from my patch. P.S. I have just checked Microsoft Visual Studio 2008 and find out that it shows "const" and "&" too.
So... Can anybody review my patch or answer my questions above (one is about type update when the value is changed and the second is about "T*" => "T*&" conversion issue in gdb)? Should I do something else to make it happen (e.g. write to the gdb-dev mailing list or something else)?
Created attachment 6085 [details] Proposed fixture with type update and a few small corrections Finally I decided to set "type_changed" & "new_type" properties in the result of -var-update command cause dynamic variables seem to be something different. Moreover, this patch also fixes type names of children that were obtained from pretty printers.
(In reply to comment #12) > Created attachment 6076 [details] > - indirect pointers (I mean pointer to pointer or reference to pointer and so > on) do not have a real type in whatis/print commands. The proposed patch does > not fix this problem because there is another problem in gdb which does not > allow to cast pointer to reference to pointer ("T*" => "T*&"). If it will be > fixed it is quite easy to provide support of indirect references too (a few > changes in value_rtti_target_type() should be enough). Please file a separate bug for the cast problem. > - the last unresolved problem is type update when value changed. I am not sure > about how it should be done. Should we just set "type_changed" & "new_type" > properties in the result of -var-update command? If so I think not all > frontends will support it (at least Eclipse will not - I have checked it). Or > maybe we should create dynamic varobj some how? Can somebody advice me > something about it? I think it is fine to add new fields to varobj without expecting all front ends to immediately respect them. So, emitting type_changed and new_type is fine. Front ends are supposed to ignore fields they don't understand.
(In reply to comment #16) > So... Can anybody review my patch or answer my questions above (one is about > type update when the value is changed and the second is about "T*" => "T*&" > conversion issue in gdb)? Should I do something else to make it happen (e.g. > write to the gdb-dev mailing list or something else)? The best way is to submit it to gdb-patches following the contribution instructions http://sourceware.org/gdb/contribute/
Some time ago I have provided a patch (http://sourceware.org/ml/gdb-patches/2011-12/msg00052.html) the fixes the problem, but have not receive any response. So I try to pay attention on it once again via this bug.
(In reply to comment #20) > Some time ago I have provided a patch > (http://sourceware.org/ml/gdb-patches/2011-12/msg00052.html) the fixes the > problem, but have not receive any response. So I try to pay attention on it > once again via this bug. We haven't forgotten, someone will review it eventually. I suggest sending a ping email after a week or so,and then once per week thereafter until someone replies.
CVSROOT: /cvs/src Module name: src Changes by: xgsa@sourceware.org 2012-04-14 12:18:51 Modified files: gdb/doc : gdb.texinfo ChangeLog gdb/testsuite/lib: mi-support.exp gdb : ChangeLog value.h varobj.c value.c gdb/testsuite : ChangeLog Added files: gdb/testsuite/gdb.mi: mi-var-rtti.cc mi-var-rtti.exp Log message: gdb/doc/ChangeLog: 2012-04-14 Anton Gorenkov <xgsa@yandex.ru> PR mi/13393 * gdb.texinfo (Print Settings): Extend the description for "set print object". (GDB/MI Variable Objects): Extend the description for -var-create and -var-list-children. gdb/testsuite/ChangeLog: 2012-04-14 Anton Gorenkov <xgsa@yandex.ru> PR mi/13393 * gdb.mi/mi-var-rtti.cc: New file. * gdb.mi/mi-var-rtti.exp: New file. * lib/mi-support.exp (mi_varobj_update_with_child_type_change): New function. (mi_varobj_update_with_type_change): updated to avoid code duplication. gdb/ChangeLog: 2012-04-14 Anton Gorenkov <xgsa@yandex.ru> PR mi/13393 * value.c (value_actual_type): New function. * value.h (value_actual_type): New declaration. * varobj.c (update_type_if_necessary): New function. (varobj_create): Call value_actual_type instead of value_type. (install_dynamic_child): distinct changed and type changed MI variable objects. (update_dynamic_varobj_children): Updated for install_dynamic_child change. All callers updated. (varobj_update): Support for MI variable object type change if the value changed and RTTI is used to determine the type. (create_child_with_value): Call value_actual_type instead of value_type. (adjust_value_for_child_access): Extended with a new parameter which specify whether the given value should be casted to enclosing type. All callers updated. Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/testsuite/gdb.mi/mi-var-rtti.cc.diff?cvsroot=src&r1=NONE&r2=1.1 http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/testsuite/gdb.mi/mi-var-rtti.exp.diff?cvsroot=src&r1=NONE&r2=1.1 http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/doc/gdb.texinfo.diff?cvsroot=src&r1=1.940&r2=1.941 http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/doc/ChangeLog.diff?cvsroot=src&r1=1.1293&r2=1.1294 http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/testsuite/lib/mi-support.exp.diff?cvsroot=src&r1=1.110&r2=1.111 http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/ChangeLog.diff?cvsroot=src&r1=1.14105&r2=1.14106 http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/value.h.diff?cvsroot=src&r1=1.200&r2=1.201 http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/varobj.c.diff?cvsroot=src&r1=1.194&r2=1.195 http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/value.c.diff?cvsroot=src&r1=1.155&r2=1.156 http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/testsuite/ChangeLog.diff?cvsroot=src&r1=1.3159&r2=1.3160
The fix was checked in.