This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: RFC: MI - Detecting change of string contents with variable objects
On Monday 18 December 2006 11:10, Nick Roberts wrote:
> > > Currently variable objects treat strings as pointers so -var-update only
> > > detects a change of address or, if the child is created, when the first
> > > character changes. The patch below detects when the contents change which
> > > is
> > > more useful. I've only tested it for C, but I guess it could work for
> > > other
> > > languages that variable objects handle (C++, Java). The function
> > > value_get_value gets both the address and string value but it's probably
> > > better to just get the string value directly.
> >
> > I think this is probably a wrong thing to do in MI. Yes, this helps with
> > char*, but char* happens to be not so important in C++ -- modern code
> > mostly uses std::string (or QString, or gtkmm::ustring, or whatever). This
> > patch does not help with those, for the frontend is required to contain
> > special code to handle string classes. As as soon as it has such special
> > code, handling char* can be done in frontend as well.
>
> You seem to be saying that because it won't work generally for C++ it should
> not be made to work for C.
Right, because it would be bad to have, in any given frontend, two different solutions
for C and C++.
> > but I think we need to avoid special-casing C while not solving any problems
> > with C++.
>
> I think it's better than nothing. If you can think of a more general approach
> that would be even better.
First of all, what's the problem? The problem as I see is that for some types,
default comparison rules used by MI is not appropriate. This problem
can be solved either by:
1. Having frontend grab the value on each step and do the comparison itself.
2. Adding some 'comparison customization' to MI.
(2) might work like this:
-var-set-comparator V "strcmp($a, $b) == 0"
then MI can set "$a" and "$b" to old and new value, and evaluate this
expression.
I'm not sure if (1) or (2) is better. (2) is slightly easier for frontend and it *might* reduce
the traffic between gdb and frontend.
But (2) has a serious problem -- for std::wstring and QString, frontend has to read
the data itself to present it to the user, since
-var-evaluate-expression
returns nothing interesting for std::wstring and QString. This suggests that we need:
-var-set-format-expression "................."
and the ellipsis part is a big problem. For QString, KDevelop does the following:
$kdev_d=%1.d
$kdev_s=$kdev_d.size
$kdev_s= ($kdev_s > 0)? ($kdev_s > 100 ? 200 : 2*$kdev_s) : 0
($kdev_s>0) ? (*((char*)&$kdev_d.unicode[0])@$kdev_s) : \"\""
and for complex data structures things can get out of control -- I don't fancy writing
programs in gdb script language.
Imagine the most complex case: std::map. Should variable object detect changes
in objects of that kind by looking at all contained elements and comparing them?
Should formatting of std::map be done in gdb, or in frontend?
If it's better be done in gdb, then I think we'd need Python binding, so that you can do:
define_python_function kdevelop_format_std_map ...........
-var-set-format-expression V "kdevelop_format_std_map($a)"
or something like that. But as I say, I don't yet sure such formatting should happen in gdb.
> > You mentioned that Insight handles char* just fine -- using
> > current MI code. What approach is take there?
>
> GDB is built into Insight as a single executable, it doesn't rely on
> interprocess communication with the frontend. It compares the displayed string
> in the watch expression window with the current value.
Ah, ok.
- Volodya