Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 350170 - Add generic events to force update of the Debug view
Summary: Add generic events to force update of the Debug view
Status: ASSIGNED
Alias: None
Product: CDT
Classification: Tools
Component: cdt-debug-dsf (show other bugs)
Version: 8.0   Edit
Hardware: PC Windows 7
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: Project Inbox CLA
QA Contact: Jonah Graham CLA
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-06-23 12:42 EDT by Nobody - feel free to take it CLA
Modified: 2020-09-04 15:25 EDT (History)
13 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Nobody - feel free to take it CLA 2011-06-23 12:42:49 EDT
There are cases when the Debug view should be forcibly refreshed. The following is Dobrin's posting to the mailing list which describes such cases.

+1 for two generic events that will trigger the update of the debug view - state and content. 
At least it is clear what deltas has to be propagated to flexible.

It has been bounced in the past multiple times. 

In our debugger we use them both: 
When symbols are loaded or unloaded, change of PC, etc - content change. 
While the target is running (no stack) other changes can occur - held in reset, switch of power modes, etc.
Comment 1 Pawel Piech CLA 2011-06-23 16:16:21 EDT
+1
We use a "context state changed" event in our product as well, to imply a change in state but not the other actions that go along with a suspended event.
Comment 2 Mark Goodchild CLA 2012-06-08 11:22:43 EDT
Can I ask if there is any further updates on this issue.

In our debugger we have some actions such as reset CPU and our user's are used to seeing some visual change when this operation takes place.  Currently no PC change  is visually shown in the views.

I certainly would support some system in which we can force the views to update..
So +1.
Comment 3 Stanislav Perepelitsa CLA 2016-12-01 09:43:17 EST
I think we can start from very simple use case:
1. Build and Debug the project.
2. Open the Registers View.
3. Select the PC register and change the PC value to an address out of program scope 
=> Step 3,the program execution cursor don't stops at the address specified(nothing is changed)
4. Restore the PC to the original value.
 => Step 4, nothing is changed
Comment 4 Colton Murphy CLA 2017-03-01 12:58:47 EST
I am implementing a DSF plugin which requires this behavior. The contents of the registers can change on the back end while the debug perspective shows the device as suspended. 

Use case:
1. User presses a button in my plugin view which causes the plugin to write to the stack pointer / PC registers on the device using GDB through DSF. 
2. DSF event should be signaled such that it tells all of the debug views to update: registers view, eclipse debug view, etc. 
3. Event causes all views relying on DSF to re read the registers and stack frame for the device via GDB.

I attempted to use StateChangeEvent but the debug views did not update. This was the course of action:
1. Launch program to be debugged using GDB server (JLink)
2. Hit breakpoint
3. Modify a CPU register through the GDB server interface (general register or PC / stack pointer)
4. Double click plugin button to make a call to the dsfSession.dispatchEvent using a new StateChangedEvent. 
5. Register view, debug view, variables / expressions, etc. views do not update.

In the above sequence if I click on one of the registers in the register view so that it allows me to edit a register and then click on another register to edit, this causes the register view to do a re read of the CPU registers through GDB. The register values that I set through the GDB server interface are now updated in the register view.

There was a thread of somebody attempting this sequence several years ago:
http://permalink.gmane.org/gmane.comp.ide.eclipse.cdt.devel/20936. This thread seems to have gone into the ether.

I expect that once the new event gets implemented, it has the ability to update the context of all views relying on DSF such as changing the PC and stack pointer of the device. This would potentially cause the debug view, register view, expression view, variables view, etc.. to update.
Comment 5 Marc Khouzam CLA 2017-03-02 09:15:25 EST
(In reply to Colton Murphy from comment #4)

> I attempted to use StateChangeEvent but the debug views did not update.

The StateChangeEvent currently only affects the Debug view and only for the label of the processes and threads (the text that is displayed).  It will not trigger a refresh of the list of threads or processes, and will not affect other views.

In your case, it sounds like you want to use IRegisters.IRegisterChangedDMEvent as the event.  This will tell the Register view and the IRegisters service that a register has changed and should be fetched from the GDB.
Comment 6 Colton Murphy CLA 2017-03-02 15:29:15 EST
(In reply to Marc Khouzam from comment #5)
> (In reply to Colton Murphy from comment #4)
> 
> > I attempted to use StateChangeEvent but the debug views did not update.
> 
> The StateChangeEvent currently only affects the Debug view and only for the
> label of the processes and threads (the text that is displayed).  It will
> not trigger a refresh of the list of threads or processes, and will not
> affect other views.
> 
> In your case, it sounds like you want to use
> IRegisters.IRegisterChangedDMEvent as the event.  This will tell the
> Register view and the IRegisters service that a register has changed and
> should be fetched from the GDB.

So I can try the register changed event, which as you say will update the registers view. What about an update of the variable, expression, and debug views? I would be sending the event to tell the register service that basically all my CPU registers have changed including the PC and stack pointer. Will this trigger an update of the other views?

I have to assume it will trigger a partial update, because as tested before, if I go in and manually change the PC, the debug view updates to show the new PC location and source file; however, it only shows the first line of the stack frame. The previous stack frame lines are stale. If I 'select' the previous stack frame lines in the debug view using the mouser, the debug view ends up updating the stale information. Changing the stack pointer in a similar manner causes the variable views to update with the local variables for the new pointer, but does not update the debug view.

Partial update means 'something' is at least happening, but I would like a full update (re read of GDB stack frame and registers causing all views to update) :). Also, am I correct in that selecting and editing a register like I have explained above would essentially be the same thing as sending the RegisterChangedDMEvent programatically? 

Thanks
Comment 7 Marc Khouzam CLA 2017-03-03 11:02:17 EST
(In reply to Colton Murphy from comment #6)

> So I can try the register changed event, which as you say will update the
> registers view. What about an update of the variable, expression, and debug
> views? 
> I would be sending the event to tell the register service that
> basically all my CPU registers have changed including the PC and stack
> pointer. Will this trigger an update of the other views?
> 
> I have to assume it will trigger a partial update, because as tested before,
> if I go in and manually change the PC, the debug view updates to show the
> new PC location and source file; however, it only shows the first line of
> the stack frame. The previous stack frame lines are stale. If I 'select' the
> previous stack frame lines in the debug view using the mouser, the debug
> view ends up updating the stale information. Changing the stack pointer in a
> similar manner causes the variable views to update with the local variables
> for the new pointer, but does not update the debug view.
> 
> Partial update means 'something' is at least happening, but I would like a
> full update (re read of GDB stack frame and registers causing all views to
> update) :). 

To get all view to update, you can do different things.
You can define your own event and change the code to each *VMNode to refresh their value/content when that event happens.  This can be tedious.

You can re-use an exiting event.  For example, sending an ISuspendedDMEvent shoudl make everything refresh.  I'm not sure what will happen if you send this even while the program is already suspended, but I believe it will work.

You could also call LaunchVMProvider.refresh() which will refresh the debug view and consequently every other views.  You can look at how this is used in the code and see if it is possible to use this method in your case.  This may be the simplest thing to do.

This particular bug here is meant to trigger the same result as calling LaunchVMProvider.refresh(), except that it would allow this to be done from the core plugins and not just the UI plugins, because it would provide an event to trigger the call.

> Also, am I correct in that selecting and editing a register like
> I have explained above would essentially be the same thing as sending the
> RegisterChangedDMEvent programatically? 

Yes and no.
If you look at generateRegisterChangedEvent() in MIRegisters.java and GDBRegisters.java, you will see that it sends both a RegisterChangedDMEvent and one more more IRegistersChangedDMEvent.  This is because changing one register can actually affect other registers, so we are forced to update all of them.
Comment 8 Bruno Medeiros CLA 2017-05-19 13:14:34 EDT
Like Mark G mentioned there are some situations where this would be useful for our product.

Another on is when debugging hardware where a certain area of memory is overlaid, mirrored from another area. Such that when you write a flag to a special area of memory, the overlaid memory area switches to a different mirrored memory mapping. 

In simpler terms, it means that writing to a memory address can change not only that memory address, but a whole range of others. And the Memory view and Expressions view doesn't currently cope with that. This ticket would help in addressing this.

I was thinking of cooking up a solution in line to that Marc Khouzam said about calling LaunchVMProvider.refresh(). It would be essentially this:
There would be a core DSF event that would signal that UI needed to fully refresh. Then the org.eclipse.cdt.dsf.ui.viewmodel.update.AbstractCachingVMProvider subclasses would listen to this event, and call AbstractCachingVMProvider#refresh whenever they received the event. (posting to UI thread of course)

I think this would address the problem in a relatively straightforward and clean way. Does this sound roughly sane, to those more familiar with DSF UI/ViewModel handling?

The only annoyance is... MemoryView doesn't use an AbstractVMProvider at all... so a different, separate mechanism would need to be used here.