Interesting debugger idea

| | Comments (17)

One of the things I was thinking about was a way to add watchpoints to the REALbasic debugger. For those of you unfamiliar with the concept, a watchpoint is a handy debugging feature whereby you can have the debugger "watch" a particular variable so that when it's changed, the debugger breaks at that point.

So let's say you have an overly complex application, and somewhere in your code base, something is setting a variable to the incorrect value. You know that when the window opens, everything is fine, but between the window opening and when you push a particular button, things go haywire. This is the perfect opportunity to use a watchpoint. In the window's open event, you would locate the variable in the debugger's variable viewer, and somehow say "watch this thing." When that thing had changed, the debugger would automatically break for you and show you what code was modifying that data. Handy, eh?

So I was thinking to myself, "how would I accomplish that feature." I think I've come up with a reasonable way to do it, too! When the user says "watch this variable", the debugger could send a watch message to the target application. Part of that watch message would be the address of that variable. The target application could then put an OS memory write protection lock on the address (spanning over the entire range that the data covers). When something attempts to modify that range of memory, the OS would fire a memory protection exception, which the target app could then handle. While handling it, it can look to see if the exception was fired due to a range in our "watch" list, and if it was, it could then send a break statement back to the debugger (and safely ignore the exception).

This is a fairly normal way to accomplish watchpoints, but would still require a bit of work. For starters, the debugger protocol would have to change. Then, there would have to be some debugger UI to allow you to set the watchpoint (which then calls the new protocol message). The debugger support on the application side would have to maintain a list of addresses for watchpoints, and be able to tell if a particular exception was on account of something on the watch list. Finally, I'd have to figure out how to write-protect a range of memory on all the platforms we support, as well as handle the exception properly for it. Oh yeah, and I bet a protocol message + UI for removing a watchpoint would be handy as well. ;-)

So it's not impossible to add this sort of a feature, but it's not a trivial matter either. However, as GI Joe taught me many years ago: knowing is half the battle (of course, the other half of the battle is violence...). So yeah, that's my neat debugger idea for the day. No clue if/when something like this would happen -- just thinking on paper, really. But I'm always happy when thinking on paper sparks a good discussion. Soooooooooo discuss!

17 Comments

I know there's a report ID out there for this...
http://www.realsoftware.com/feedback/viewreport.php?reportid=irkoxysh

??

That RSS link on the reports view is such a tease.

That bug report is asking for an expression to watch, which is not what the above post covers. Expressions are more tricky in that it's something you have to evaluate at proper times. A closer report would be:

http://www.realsoftware.com/feedback/viewreport.php?reportid=pjakmall

Or, add a separate feature that has other added benefits: virtual properties. When debugging, optimizations for devirtualizing the properties could be omitted, and breakpoints could be set on the actual property setter. Then we wouldn't rely on features of individual operating systems :)

Ah, but that comes at a cost. Memory corruptions are a pain to track down, and your suggestion wouldn't help with that. Those of us who regularly work with declares can really benefit from a true watchpoint system, and the only way to capture that is by using memory protection.

A neat corollary to this would be a way to (optionally) flag a memory to see if it's used before being initialized. Yes, RB initializes things to zero, but this would be a trivial addition once watchpoints were done (mark the memory area as no access -- upon a write attempt, allow the write operation and flag full access. By doing this, you can see if something attempts a read before a write on a particular area of memory).

It does seem that if there was a way to hook into a "getter/setter" pair of methods it might be easier; althogh that could involve code rewriting ,etc.
A break in the setter would cause a break and voila we have a watch point.
What that might not catch is the "accidental overwrite" which should never happen but the memory lock would catch that case as well.
Seems that a way to catch even accidental memory alterations would be a good feature.


To be honest while watch points would be very handy I can sort of do this for myself now by using computed properties and/or getter/setter methods and appropriate break points.

I know at one time you had said that focusing on things that cannot be done or fixed by users may end up providing more utility in the long run and I'd tend to agree.

There are a few bug reports that really could stand to be fixed. The folderitem bug I reported would be nice. Or feature requests that users have no ability to add or affect.

In the long run watch points will need to be present, but these other items might take priority for now.

@Norman -- memory overwrites shouldn't happen, but with plugins, declares, and (more recently) the Ptr data type, they are certainly something you can run into with day-to-day programming.

And I never said this was being actively worked on. I was just kicking the idea around.

Aaron - I like the idea of a memory protection exception as that can catch all those wonky things that could happen with declares which could be the hardest to track down.

I realize that this may not be "active" and sometimes the gestation period is long.

Just saying that I do believe the goal of making impossible things possible and fixing the unfixable has a lot of merit.

Since there is sort of a way a user can do a watch point now the discussion and gestation on this can be kind of long without too much detriment.

I agree with the goal of getting the "impossible" in there.. but remember, people can't find memory corruption issues with our debugger either -- it's "impossible" to do anything automated. It happens more than you'd think, too.

In any event, this is just a musing (not to be confused with "amusing") on my part. The good news is, it's something I'd be comfortable adding to the debugger myself (whereas there are still other issues which I don't think I'd be able to tackle on my own).

@DeanG -- I see what you mean about the RSS feed thing. It should either not be there, or it should be functional like you would expect. You should file a bug report against the feedback system itself about that one.

Aaron ... I suppose a nice way to find the corruption would be very good for that reason. I'm manging to do a really good job on it with writing to LDAP servers :)
Damed C structures of pointert to pointers to pointers and such :)

I realize this is not a "done thing" and that talking out item sometimes helps.
I didn't mean to imply that there was nothing else going on as well.

I think the protected memory way sounds more complete as a plugin or decalre could nuke your memory as well.

I'm positive that I filed a feature request for "watches" years ago. However, I can't find it, but signed on to a number of others. Perhaps that should be merged together. O:)

@Aaron
Thanks for finding the exact watchpoint link. Signed on!
Here's the new link for feed enabled Report queries:
http://www.realsoftware.com/feedback/viewreport.php?reportid=gjapwmru

Whether the feature is considered development or not, the closer it get's to Quick-Fix status.. :D

(Hmm.. Here
s a Quick-Fix I'd like. :D http://www.realsoftware.com/feedback/viewreport.php?reportid=nmwaxgfm )

H Aaron,

I replied to you directly but I get a bounce from aaron@aaronballman.com
Just a heads up

@Gerard -- that's strange, I'm not getting any bounces with my test messages. Can you try again (and cc my realsoftware account)?

I do miss watchpoints ... I really liked them in the Think Pascal IDE way back when

- Karen

What's the granularity you can request for write protected memory? If it's a page, then you're also going to have to check whether the exception was caused by a valid write to a nearby location within the page and find a way to allow all of those kind of writes to proceed.

And a watchpoint is only useful to detect memory corruption if you apriori know the corrupted memory location to watch for.

RB, being a highlevel language, doesn't give us a view into the memory map at all. All we know about are variable and method names. A bad declare obviously can stomp on memory almost anywhere. So rather than watching for memory corruption based on LOCATION, it might be more useful to watch based on TIME. eg Show me the memory locations within my app's memory space that changed immediately after calling a declare.

But I agree with Norman, basic bug fixing and fundamental framework features should take priority.

I'm pretty sure it's a page level resolution, so you're right that a bit more bookkeeping is needed. But I really like the time-based watchpoint. That's a really interesting idea.

Leave a comment

Disclaimer

I'm currently an employee of REAL Software. My blog is mine. The opinions represented in this blog are mine as well and may not represent my employer's opinions. All original material is copyrighted and property of the author.

REALbasic® is a registered trademark of REAL Software, Inc. REAL SQL Server™ and Lingua™ are pending trademarks of REAL Software, Inc. All rights reserved.