Last time, I spoke about why I thought the remote debugger stub needed to be rewritten. Today, I'll start to delve into the actual process.
I toyed with the idea of trying to keep backwards compatibility, but since the entire IDE was being rewritten, I didn't think it would be too outlandish to say "you have to use the upgraded remote debugger stub" so long as there was no conflicts. Meaning that the old IDEs can't discover or communicate with the new stub and vice versa.
At this point, I had a goal in mind -- make the remote debugging stub work more reliably, ensure that it's very easy to install/setup/work with, and make it more extendable. Initially, I was just going for feature parity -- so it wasn't going to have the ability to transfer folders or do anything spiffy. So I started drafting a few ideas out on paper to see how things would flesh out, and I realized, "since you're already breaking things -- why not make it worthwhile and add some new features?" So that's how the new remote debugger stub really began to take shape. I started looking through various feature requests about remote debugging, as well as bug reports so that I could get a better feel for what users wanted it to do. I already had a list in my head of things I thought it should do better -- I just had to make sure I listened to the people who pay the bills. ;-)
So I came up with a rough list of necessary features. It looked something like this:
- Needs to be easy to set up. Auto discovery is a must, but also try to keep the firewall fiddling to a minimum as much as possible.
- Remove as much of the reliance on UDP as possible so that the stability is improved. This is especially important for people running wireless networks.
- Be able to transfer files or folders so that we can debug Mach-O applications. This also gives the ability to send support files to the remote machine along with the debug application. So, for example, you could send your database files, pictures, sounds and other external support files.
- Make the protocol extendable. This includes adding a handshake process and versioning that allow for backwards compatibility.
- Add extra security features so the stub is harder to abuse. This also means allowing the user to set a password on the remote debugger stub so that it can be protected.
- Let the stub pick which network interface it listens on so that people with multiple NICs have choices.
- Make the IDE responsible for telling the stub what to do. For example, the stub doesn't guess when to launch the file, the IDE tells it when to launch.
So with these thoughts in mind, I set out to rewrite the protocol. At first, things went quite well. I spec'ed out about a 4 page document that was a very rough draft of the protocol. I went about it in sequential order in terms of how the IDE and stub would communicate. So I designed the handshake first, and once that was done, I designed information exchange (such as what platform the stub is running on, etc), and so on. Everything seemed to be alright, so I decided to send the rough draft around to people here at work to see what they thought of the design.
I was glad I did that because some people had good ideas on how to improve things. Specifically, Joe, Mars and I discussed how to make the security handshake better, and the idea we settled on was both elegant, simple and secure. By-and-large, I only got a few comments back about the spec. I think it was mostly due to the fact that it was about 4 pages long and everyone was busy with their own stuff. Oh yeah, I suppose you may like to know when this was happening: late April of 2004. I actually started the design process in early March (that's right, before REAL World even!).
At this point, I realized that I really wanted a finalized, comprehensive document that explained the protocol in detail. It had to document how the stub and IDE interact, what assumptions I was making and even show use-cases of how the protocol actually communicated. So I spent the next day or so documenting in great detail how the protocol would work at a high level. It didn't go into any implementation details like what classes to use and how to structure the program or anything like that. I just wrote down things like what the protocol is being layered on top of (which is TCP), what the structure of each packet type is and things of that nature. Once I was done with the entire design and detailing of the protocol, I started writing out communications by hand using the details of the spec. This proved to be a great idea because it immediately showed me where I was missing things that I needed to account for. I didn't sink a whole lot of time into coding up the design only to find out that the design was too limiting since I was able to learn the limitations early on and account for them. I wrote out communications for what happens during failures, successful debug sessions, hacking attempts, etc and made sure the protocol was reasonable for each of them.
After getting everything sane-looking on paper, it was finally time to start implementing everything. I started working on the actual implementation about mid- to late-May of 2004 and went whole-hog writing it using REALbasic. The previous remote debugger stub was also written in REALbasic, but the difference this time around was that the IDE was also written in REALbasic. Also, the first version was written before auto discovery and the Easy networking classes (which is actually how those classes came into being -- they started out as fun projects that I rolled into the remote debugger stub and finally finished off into REALbasic framework classes). So this time around, I didn't have to fiddle with writing two different sets of networking classes (one MwRB, the other C++) which made the development time both quicker and slower.
The development process was quicker because I was using a set of networking tools that I designed and wrote, and are a lot easier to work with than C++ networking code. Granted, a lot of the C++ code is structured very similarly to the APIs you use in REALbasic, but it's still not as simple to use. So I was able to churn out a handful of networking classes that the remote debugger stub and the IDE could use to communicate. I didn't bother hooking them up right off the bat, mostly because the new IDE was no where near ready for remote debugging. Instead, I made a fake "IDE" application which would only do the setup and file transfer portion of debugging, and the stub side basically had no UI to it. Immediately I realized that I was missing something -- decent debug logs that describe the exact packets that were being transferred and received. So I implemented a logging mechanism which would log every single interaction between the two applications -- I didn't need to muck around with ethereal on both machines to see how the traffic went. This helped make debugging a lot easier because I was quickly able to eyeball the issues and go "oh yeah, this method is messing up", which is quite difficult to do when you're debugging the application with the debugger. This is especially true because there are various timeouts involved, so if I was debugging one part of the code, the remote side would generally just timeout before I could really get the issue solved.
Tomorrow, I'll talk more about the rewrite and get into things that went wrong. Stay tuned. ;-)
Yowza this is good stuff. Keep it coming! I wonder if there's a VB engineer who weblogs this level of detail? I'm betting the answer is no :)
Glad you're liking it! I was kinda worried that the lack of comments lately meant people think I am boring. :-P
Never boring, usually confusing, but never boring. But I'm enjoying extends at the moment and headbanging ODBC so what do I know
LoL, you're learning -- which is something every good programmer is constantly doing. I can help with extends questions, but I'm database-stupid and gleeful about it.
If you find things posted here that are confusing, keep asking questions about them -- I'm always happy to answer.
As someone moving all my work into RB, after using other tools for many years, it is dialogs like these that make me more confident in my decision. Please do continue on such topics.