Thursday, May 10, 2012

The world needs more Debug Tools

The world needs more debug tools. Well, Developers in this world do, anyways. Lately I've been learning Cocoa and ObjectiveC -- still the best way to write native iOS applications, if you don't mind the learning curve, and a lot more mature than Firemonkey is, yet -- and besides the beauty of the Cocoa frameworks and CocoaTouch (the iOS version of desktop Cocoa), one of the other things that is impressing me, is the tools that come with XCode, including "Instruments".
For a quick tour, read this link for an example of some of the things that you can do with it. Since reference counting is used everywhere in ObjectiveC, you need to know about things like retain cycles, for instance. Memory leaks in Delphi applications are more often because the "owner" didn't free an object when the owner was destroyed or no longer needed the object, although of course, reference counting does happen wherever you've got Interfaced objects. AQTime is the closest tool to Instruments, if you want to compare. But most Delphi developers don't own the full AQTime product, and Instruments comes with XCode. In fact, perhaps the most amazing thing about XCode is that it's free. Why is it free? Because Apple wants people to make iOS apps and Mac apps, and because until they took over making their own SDK, one of the big barriers to development on Apple devices, a long long time ago, was buying MetroWerks CodeWarrior, which was the Apple C/C++ IDE back in the bad-old-days prior to Mac OS X, and the iPhone, and every other cool thing.
Even though I have AQTime "Embarcadero Edition" that comes with XE2, and even though I've had AQTime Professional at various places where I've worked, I still feel that I don't have enough tools to find the difficult bugs.
I want a tool that will:
  • Help me step back in time to what happened right before the mess I'm in right now.
  • Slow down time but not stop it, giving me a way to run my code at not-exactly-full-speed, but at a usable enough speed, that I can operate the application, while seeing the mechanics of the app run, or fly by me on the screen.
  • Show a call stack, like a debugger, but also a call history, that goes back in time, until the beginning of each thread or a certain limit (say, 10000 entries per thread) is reached. Obviously the art here is knowing how much to hide and how much to show, and not only deleting the oldest entries, but also providing ways to creatively "fold" the history so that repetitive details that you don't care about could be ignored.
  • Log things without writing logging code. The current debugger can do this if you don't mind spending a lot of time doing the creation of breakpoints that don't break, but just log stuff. I also like to write logging via code, for production use, and I'm a big fan of CodeSite, or of just roll-your-own trace logging. But I want to profile code and trace its running,way beyond even what AQTime's function tracing can do. I think that AQTime is amazing, but I am sure more can be done. For example, I typed in FRED into an input box. I want to see the parts of the call tree, that have to do with the button I clicked, and the Edit box I typed fred into. I want to follow Fred, through my program. I want mouse clicks to initiate tracing just until I get back into the TApplication process-message-loop.
    Like many things, I know I'll have to write it myself if I want it done right. The thing I don't know is how to start it. If I had the starter-codebase for a simple Application Profiler written in Delphi, I am sure I could extend it and try some of my ideas. Anybody know how to write a profiler for Delphi?

    Update: Visual Studio people have something called Debugger Canvas. If you have Visual Studio 2010 ULTIMATE edition, check this free add-on out. And even if you don't do Visual Studio you should watch this video.
  • 1 comment:

    1. Well, I think it should be possible to show some kind of stack history. You can take 2 approaches: instrumenting and sampling.
      For instrumenting you need to tell the profiler which functions/units to profile, with sampling you don't have to but it tries to take 1000 samples per second of the current stack.

      If you some delphi code: take a look at my asmprofiler: it contains both a sampling and instrumenting profiler. For the instrumenting profiler you need to check which units you want to profile, and then it logs every call (! so used lot of memory, but more exact measurement than AQTime?). It's not perfect, more some kind of improved proof of concept, but it works and it's open source :)