[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
[
List Home]
Re: [cdt-dev] Freeze invisible GDB variable objects
|
Some more information about this topic:
As mentioned before, when scrolling down in a expanded struct CDT
immediately gets the values of the newly appearing struct members. I
guess this is initiated by the 'SWT Tree's 'virtual' feature (by which
the tree is not created up-front, but only when the items are actually
shown). Unfortunately, once the items were shown, no more SWT events are
processed by CDT when scrolling up and down (I enabled various tracing
levels - but no traces appear when scrolling). => Therefore, nothing
within CDT seems to be aware of which items in a tree are visible and
which are hidden (unless I just didn't find that piece of code).
Furthermore: As mentioned in a previous post, CDT executes a
'-var-update 1 varX' after certain debug event (e.g. after a single
step). This causes GDB to read the values of all non-freezed members of
'varX' from the embedded system. One important thing to be aware of, is
the fact that GDB does not even refresh the value of a frozen variable
(i.e. member of a struct) when it's value is explicitly requested. That
makes sense, but it complicates the solution for this issue: Whenever
the user scrolls within the members of a struct while some of the
members are frozen it's not sufficient to explicitly fetch the values of
the newly appearing members, because GDB would still return old values
for them. Instead, CDT would need to first change the frozen state of
these variables followed by a '-var-update 1 varX'.
Summarized:
- We'd need to react on scrolling (and any other graphical event that
may change visibility of expressions. That could probably be done by
registering to the various SWT events)
- Upon graphical changes, we'd need to:
- check which (sub)expressions are visible
- update the 'frozen' status
- execute a '-var-update'
I've no implementation for this, but I've implemented a prototype that
does parts of this: After every debug event, in
VariableVMNode.update(final IExpressionUpdate update), it walks through
the TreeItems of the expression view. (got by
PlatformUI.getWorkbench().getWorkbenchWindows()[0].getActivePage().findView(IDebugUIConstants.ID_EXPRESSION_VIEW);).
Then it checks which items are currently visible (based on the method
shown here:
http://git.eclipse.org/c/platform/eclipse.platform.swt.git/tree/examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet358.java).
The result of this is a 'range' of visible children of the expression
that'll be updated. That range (e.g. 4...8) is stored within
MIExpressionDMC (which has been extended by two members to store that
range). In MIVariableManager.getVariable(...), that range is extracted
from the MIExpressionDMC and forwarded to the MIRootVariableObject which
in turn updates the 'frozen' state of its MIVariableObjects. They
finally execute the GDB '-var-set-frozen' command if the frozen state
changed.
The prototype seems to works and it CDT performs MUCH better with huge
structs. Also, if a struct is collapsed, all it's member will become
frozen and hence the '-var-update' executes in virtually no time. BUT
I'm quite unhappy with the implementation. It feels more like a hack
than a solutions to me and that makes me unsure how to proceed from here.
If desired, I could push this (ugly) prototype to Gerrit if that helps
to get more information/tips from experts on how to proceed.
Raphael
On 08/14/2014 02:29 PM, Raphael Zulliger wrote:
On 08/14/2014 12:38 PM, Pascal Rapicault wrote:
On which criteria would the framework emit those commands?
Not quite sure on what your question focuses. But beside the question
how to implement it, in the ideal world, CDT would behave like that
(IMHO):
Assume we're in the Expression View, having two root items both of
type class/struct and both contain some members, like this:
======================================= (This is the view top border)
| |_ MyObject | {...} | (assume varobj name="var1")
| |_ m_Member1| value 1 | (assume varobj name="var1.m_Member1")
| |_ m_Member2 | value 2 | ...
| |_ m_Member3 | value 3 |
| |_ m_Member4 | value 4 |
| |_ MyOtherObject | {...} | (assume varobj name="var2")
| |_ m_Array1[20];| {...} | (assume varobj
name="var2.m_Array1")
| |_ m_OthrMember2 | value 2 |
| |_ m_OthrMember3 | value 3 |
======================================= (This is the view bottom border)
|_ m_OthrMember5(invisible - therefore don't get value
fromembedded target)
|_ m_OthrMember6(invisible- therefore don't get value from
embedded target)
|_ m_OthrMember7(invisible- therefore don't get value from
embedded target)
...
In that situation, there are more members than can be shown without
scrolling down. Therefore, from "m_OthrMember4" (which is hidden below
the bottom border) and further below, no more members are visible.
Therefore, it is a waste of resources to refresh them, as CDT/GDB is
doing it today. This especially hurts if a struct contains hundreds of
members (e.g. a struct that represents hardware registers with
hundreds or even thousands of members which can easily cumulate to a
total size of 1MByte which happen to be refreshed on every debug
event).Btw: this happens because CDT executes a '-var-update 1 var1'
and '-var-update 1 var2' on every debugging event. And because CDT
didn't freeze any members, GDB will just update all members, resulting
in reading all the memory of the struct from the (embedded) target,
e.g. 1MByte(!).
If you're question focus on the "how to notice when a member appears
or disappears" from the visible range, e.g. because the user is
scrolling and the like: Well, that's exactly what my initial post
tries to find out.
Right now, as I'm writing this, I realize that CDT already does
something like that. E.g. when initially expanding a struct (e.g.
MyOtherObject), then CDT does only execute '-var-evaluate-expression'
on the visible items (m_Array1, OthrMember2and m_OthrMember3in this
example). Then, when I scroll down in the Expression View, so that
m_OthrMember4 appears, CDT executes another "-var-evaluate-expression"
for var2.m_OthrMember4, right when that member starts appearing. I
might study that code to find out more...
Raphael
On 14/08/2014 10:52 AM, Raphael Zulliger wrote:
Hi
To increase debugging performance when having huge data structures
in Variable/Expression View etc., I'd like to make extend CDT with
GDB's "-var-set-frozen" or "-var-set-update-range" features (see
https://sourceware.org/gdb/current/onlinedocs/gdb/GDB_002fMI-Variable-Objects.html).
I'm still quite unfamiliar with the ViewModel concept and how it
finally links to the UI. Therefore, can someone point me towards a
good starting point regarding: How can I know which elements in the
Variable View, Expression View are currently visible? (i.e. if there
are 1000 members in a struct, the view will at most show a few
dozens, depending on the height of the view - all others are
invisible). How could I get notified about changes (e.g. the user
scrolls down the list)?
Any idea/hint would highly be appreciated!
Thanks,
Raphael