[PATCHv2 2/2] gdb/fortran: Access elements of a structure with dynamic type
Andrew Burgess
andrew.burgess@embecosm.com
Thu Aug 6 15:38:37 GMT 2020
* Tom Tromey <tromey@adacore.com> [2020-08-04 13:19:39 -0600]:
> Andrew> The behaviour of this flag seems like it should be don't access the
> Andrew> target unless it's required to correctly do the task we're trying to
> Andrew> do. But it seems like a working lazy value system should give the
> Andrew> same result.....
>
> Andrew> .... but I'm probably missing something.
>
> Tom> I've never been completely clear on the intended semantics of
> Tom> EVAL_AVOID_SIDE_EFFECTS. It refrains from reading inferior memory,
> Tom> usually (?) -- but is that really needed?
>
> Tom> One argument would be that ptype should just evaluate the expression,
> Tom> and that for 'ptype x++', well, you got what you asked for.
>
> Tom> A plus side is that scenarios like the one you present wouldn't be
> Tom> possible.
>
> Tom> A minus is that things like "ptype variable" would maybe no longer show
> Tom> the declared type, but rather the dynamic type.
>
> Tom> Speaking of, your scenario seems a lot like the C++ "set print object on"
> Tom> scenario. There, the dynamic type is pretty much only used when
> Tom> printing. I wonder if that makes sense for Fortran.
>
> This issue has also come up in my work to make the Ada support in gdb
> work with DWARF debug info (rather than the "gnat encodings" which are
> normally used). Here, many Ada types now use dynamic properties and are
> resolved to concrete types using resolve_dynamic_type.
>
> One thing I was thinking about is that with the "do not evaluate"
> approach, there is a difference between:
>
> (gdb) print x
> (gdb) ptype x
>
> and
>
> (gdb) print x
> (gdb) ptype $
>
> Here, only the second evaluation would show the dynamic type.
>
> This seemed unnecessarily obscure to me, and I started leaning toward
> the view that ptype ought to evaluate. However, I found that the
> current behavior is explicitly documented:
>
> If ARG is an expression (*note Expressions: Expressions.), it is
> not actually evaluated, and any side-effecting operations (such as
> assignments or function calls) inside it do not take place.
>
> Now, Joel pointed out to me that the Ada expression evaluator already
> does something like what is in the patch up-thread. See "case
> OP_VAR_VALUE" in ada_evaluate_subexp:
>
> if (noside == EVAL_AVOID_SIDE_EFFECTS)
> [...]
> /* Tagged types are a little special in the fact that the real
> type is dynamic and can only be determined by inspecting the
> object's tag. This means that we need to get the object's
> value first (EVAL_NORMAL) and then extract the actual object
> type from its tag.
>
> Note that we cannot skip the final step where we extract
> the object type from its tag, because the EVAL_NORMAL phase
> results in dynamic components being resolved into fixed ones.
> This can cause problems when trying to print the type
> description of tagged types whose parent has a dynamic size:
> We use the type name of the "_parent" component in order
> to print the name of the ancestor type in the type description.
> If that component had a dynamic size, the resolution into
> a fixed type would result in the loss of that type name,
> thus preventing us from printing the name of the ancestor
> type in the type description. */
> arg1 = evaluate_subexp (NULL_TYPE, exp, pos, EVAL_NORMAL);
>
> So, this is a bit of a funny situation, where on the one hand the code
> respects the "avoid side effects" rule (assuming the target isn't using
> memory-mapped I/O that is overlaid by some Ada data structure ;), while
> also avoiding the spirit of the thing ("not actually evaluated" -- here
> in some cases it is).
>
> My understanding is that this particular tweak came from a user request.
> You can see here that it was definitely intentional:
>
> https://sourceware.org/pipermail/gdb-patches/2008-September/060193.html
>
>
> One idea that came up on irc was to use a flag to ptype to select the
> mode. I think that would be fine -- though it still leaves the question
> of which mode ought to be the default; and the question of whether we
> ought to remove cases like the above from the code.
>
> Perhaps a related question (mentioned above as well) is whether "set
> print object on" ought to be ignored in favor of this flag.
>
> Maybe one final weirdness is that if ptype evaluates, since the value
> isn't entered into the value history, there's no way to refer to it
> again without re-evaluating.
>
>
> I am not completely certain but my current proposal would be:
>
> 1. ptype should evaluate its argument by default, and should show the
> runtime type. I'm not concerned about the value history thing,
> because I think I tend not to use ptype on side-effecting expressions
> anyhow.
>
> 2. We should add a flag to ptype, say "/s" (for "static type"?), to have
> it not try to evaluate, but instead print the static type.
>
> 3. We should remove any special cases for EVAL_AVOID_SIDE_EFFECTS, since
> presumably they won't be needed any more.
>
> 4. For "ptype/s $", I guess we will need to have a back-link from the
> resolved type to the dynamic type. (FWIW I have a patch I wrote to
> experiment with this...)
>
> 5. We should ignore the "set print object on" problem entirely. For
> ptype/s, we should differentiate between "runtime type" and "concrete
> instance of dynamic type", and only try to use back-links for the
> latter.
>
>
> What do you think?
FWIW, I think this would be a good direction to move in.
Thanks,
Andrew
More information about the Gdb-patches
mailing list