Author Topic: RFI: Give codeblocks debugger events posibility to signal what watch triggered  (Read 6219 times)

Offline BlueHazzard

  • Developer
  • Lives here!
  • *****
  • Posts: 3353
Hi,
i currently work on my MemoryWatch plugin.
With this plugin it is possible to view multiple memory ranges at the same time. For this i use multiple memory watches.
Every memory watch triggers an update memory window event. But it is not possible to know what watch has triggered this event.
This is unfortunate because it has this problems:
1) For every watch, all windows get updated
2) I want to highlight the changed memory range. For this i check on every update the memory buffer and compare it with an saved buffer.. But this does not work, because on every watch update all buffers are updated, also if this is the same debugger state...

So my request for ideas is to somehow add the watch to the event. But i have no idea how...
Introduce a debugger only event with a reference to the cbWatch?
Add a generic pointer to the generic CodeblocksEvent?

Offline oBFusCATed

  • Developer
  • Lives here!
  • *****
  • Posts: 13413
    • Travis build status
Hm, why are you sending more then one update request?
Why don't you gather how many watches need to be requested and then do this in one go?

I suppose we could add "generation id" or something similar to the cbEVT_DEBUGGER_UPDATED, so you can detect which event you're currently handling. Would that work?
(most of the time I ignore long posts)
[strangers don't send me private messages, I'll ignore them; post a topic in the forum, but first read the rules!]

Offline BlueHazzard

  • Developer
  • Lives here!
  • *****
  • Posts: 3353
Quote
Hm, why are you sending more then one update request?
I was wondering the same and i will investigate, but this does not solve the Problem. The function
Code
DebuggerGDB::AddMemoryRange(uint64_t address, uint64_t size, const wxString &symbol, bool update)
has an update flag, that triggers the update for all windows. So lets say we are paused, the user adds a memory watch ->  all windows are getting updated, but only one watch has really new values. This triggers the problem that i have with my internal buffer gets overwritten for all windows. I probably could mitigate this, by looking if the debugger state has changed (listening to cursor changed ecc) but then again, i do not know what watch is new...

Quote
Why don't you gather how many watches need to be requested and then do this in one go?
See above. This works on pause event, but not when a user adds a new watch...

Quote
I suppose we could add "generation id" or something similar to the cbEVT_DEBUGGER_UPDATED, so you can detect which event you're currently handling.
can you explain more what this generation id is?


Offline oBFusCATed

  • Developer
  • Lives here!
  • *****
  • Posts: 13413
    • Travis build status
You can use update=false and batch update them.

A generation is a monotonically increasing number which is stored in every watch and marks when it was last updated. You can then do some comparisons to see if this watch has been updated in this update request. This won't be very reliable probably.

Another option is probably requestion updates per window, which will probably be faster, if there are tabs and some windows behind other windows.
So every debug window will have some unique id and every element (watch in this case) in it is associated with this id, so when an update request is made, this id is passed to it and only elements matching the id are updated.
Unfortunately this prevents showing the same element in multiple different views. But I'm not sure if this is something which will be useful.

Or I guess we could add a field in the event object which designates what is the reason for the update.
For watches it makes sense to show differences only if the reason for the update is a change in "active frame".
If the user requests an update using the context menu or because it has just added the watch then I'm not sure it makes sense to show the diff.

Hm, lots of options, probably the last one seems most useful...

p.s. the address of the current frame could be stored in the watch object, too, so it might be used to do comparisons.
p.p.s. I guess I could think of more variants to solve this the more I think about it :)
p.p.p.s. You don't need to store the watches in the event object, you could store it in the debugger plugin and provide an API. Something like GetListOfLastUpdatedWatches()...
(most of the time I ignore long posts)
[strangers don't send me private messages, I'll ignore them; post a topic in the forum, but first read the rules!]

Offline BlueHazzard

  • Developer
  • Lives here!
  • *****
  • Posts: 3353
I created a pull request with the beginning of the idea. This works fine for memory watches, that are not updated automatically, but only on request...
https://github.com/obfuscated/codeblocks_sf/pull/19

[Edit:]
The idea is that:
1) Own CodeblocksDebuggerEvent, with a cbWatch field. If a single watch is updated this field is populated. If it is a collection of watches that are updated it is empty
2) Watches have an automatic generated unique id. First i wanted to use the watch asdress to compare, but with shared_ptr and different derived and base class it seems that there are different pointers for every derived class.
3) Now on a Update event i can look if this event is for my watch and update only accordingly...

Quote
You can use update=false and batch update them.
But what is when i add a new watch when the debugger is halted. Then all other windows are too, and we have the old problem of windows get updated that should not...

Quote
Another option is probably requestion updates per window, which will probably be faster, if there are tabs and some windows behind other windows.
This is kind of what i am doing now... Debugger halts -> Request for update of visible watches -> With the watch id in the event i can assign them to the right window

Quote
You don't need to store the watches in the event object, you could store it in the debugger plugin and provide an API. Something like GetListOfLastUpdatedWatches()...
I think storing the watch in the event is the easiest way and also async proof. We are using shared ponter already so this is not costly...

« Last Edit: March 22, 2021, 10:49:44 pm by BlueHazzard »

Offline BlueHazzard

  • Developer
  • Lives here!
  • *****
  • Posts: 3353
Closing pull request without any comment? Was it so bad?

Offline oBFusCATed

  • Developer
  • Lives here!
  • *****
  • Posts: 13413
    • Travis build status
If I do a proper review you'll loose your motivation to do it and you'll leave it as is. So I've wasted my time and there would be no progress. Loose, loose kind of situation.
I've told you what I'll do, from the PR title it seemed like you've ignored what I've told you.
So go on an push it. If it doesn't work, I'll fix it later.
(most of the time I ignore long posts)
[strangers don't send me private messages, I'll ignore them; post a topic in the forum, but first read the rules!]

Offline BlueHazzard

  • Developer
  • Lives here!
  • *****
  • Posts: 3353
Quote
If I do a proper review you'll loose your motivation to do it and you'll leave it as is. So I've wasted my time and there would be no progress. Loose, loose kind of situation.
Yea, it frustrates a lot and sometimes we turn into circles, but i learn even more from your reviews, so they are very welcome! At least some general code review...

Quote
I've told you what I'll do, from the PR title it seemed like you've ignored what I've told you.
I have not ignored them... I even implemented some (a lot hours), but they did not work as expected... So I used a mix of them and implemented this pull request....