Dr. Dobb's Journal June 2000
I'm on the road again in the Titanic, the Stevens family motorhome. The photo at the bottom of this page is the Titanic refueling, and it shows that even when on the road, I am well supported by Jon Erickson who, as always, puts the needs of his favorite columnist first and foremost. This particular Dobb's division can be found in Lumberton, North Carolina.
That was yesterday. As I write this, the Titanic is not only my home, it is my exile. I'm just north of Harrisburg, Pennsylvania, sitting at a gas station/convenience store waiting and waiting for someone to come and replace a blown-out tire on this ol' house. RV manufacturers don't put spares and jacks on these big vehicles; they're afraid some old guy like me will hurt himself trying to change one and they'll get sued. With tires the diameter of a typical crop circle, they're probably right. They figure I'd rather sit it out and wait for a service truck that never comes.
I blew out the tire myself putting air in it at the fifty-cents-for-three-minutes air pump at this convenience store. It bugs me to have to pay for air. Particularly when, after putting in a buck and a half's worth, only 70 PSI in a 90 PSI tire, all I get is a big loud bang while all my expensive air returns to the, er-uh, air. Oh, yeah, and continuous ringing in both ears for I don't know how long.
The family, consisting this time of wife Judy, daughter Wendy, and Wendy's three sons (including Spencer, a new clan addition, three-weeks-old and perfect in every respect) have abandoned me to head for the farm. They were rescued by a sister-in-law who has a motor vehicle with all its tires properly inflated. The proprietors of this convenience store walk by every now and then and peer in my window at the strange hermit secretively typing away at a laptop and apparently hunkered down for a while. Eventually, they'll beat on the door and ask when I plan to vacate the premises and free up the seven or eight parking spaces I occupy. Until someone shows up with a tire that would fit a 747 nosewheel is when, and until then I'll bide my time and get some work done.
All things considered, this isn't a bad way to be stranded. There's plenty of food and drink in the reefer, a decent stereo and my Miles Davis CD collection, a working computer, cell phone, comfortable bed, even a furnace to keep me warm on this chilly March afternoon. And if I run out of beer and pretzels, the main staples of a road journalist, my new neighbor is a convenience store. How convenient. It reminds me of those tiresome old desert island list questionnaires. If you were stranded on a desert island, which C++ compiler would you want to have along?
My new year's resolution was to upgrade Quincy 99 substantially and release Quincy 2000. Quincy, as many of you know, is a Windows-hosted IDE for C and C++ development, and you can download it from http:// www.midifitz.com/ alstevens/quincy99/. Quincy's purpose is to help teach C and C++ by providing a student-oriented environment conducive to writing and studying simple command-line and GUI programs. Starting this month, I'll discuss the design and implementation issues of this 2000 upgrade. The ongoing project is available in its progressive stages of implementation at http://www .midifitz.com/alstevens/ quincy2000/.
Quincy 99 operates as a front end for the gcc-mingw32 compiler suite. (Gcc is a free open-source compiler suite from the community of gnu volunteers. The mingw32 port of gcc uses Win32 as the host and target platforms.) Among the improvements I want for Quincy 2000 are a new programmer's editor, improved debugging features, more tools for GUI development, and a Standard C++ Library. The first three features are under my control and work is underway. The last feature depends on those dedicated volunteers who are developing the Standard C++ Library for gcc. The library project is not only slow in coming, it shows promise of being something less than efficient in its implementation. I reported some simple benchmarks last month. Not bad for the price, which is free, but not as good as it ought to be and no guarantee when a fully compliant library or reasonable facsimile will be available. To achieve my objectives in the near term, Quincy needs a different free compiler.
Last month, I reported that Inprise released the command-line version of its BCC32 Borland compiler for free download at http://www.borland .com/bcppbuilder/ freecompiler/cppc55steps .html. As my deadline for last month's column approached, I was unable to download it. The problem went away a day or two later, and I now have the full release along with membership in the official Inprise/Borland online user community.
I also reported that the Borland compiler, being free, might be a good alternative for gcc-mingw32 as Quincy's compiler. The Borland compiler scores high on tests for Standard C++ compliance, and Borland uses the Rogue Wave libraries, which are reasonably compliant, probably more so than those of any other free C++ development environments.
One problem with integrating BCC32 into Quincy involves the redistribution rights. BCC32's license does not permit downloaders to distribute the compiler with other products, an understandable restriction. After all, this compiler is the foundation for Inprise's C++Builder development environment, and they cannot be expected to contribute to the efforts of their competition. Nonetheless, I developed the first version of Quincy 96 four years ago to accompany books and CD-ROM programming tutorials, and the compiler is an essential component of such distributions. Unless Inprise makes an exception for book writers -- me in particular -- those products will necessarily include only the gcc compiler. There is, however, nothing in the license that prohibits me from revealing to users where they can download the BCC32 compiler, and that fact makes viable the integration of BCC32 into Quincy 2000 as an option.
The other problem involves Quincy's debugger, which extracts source-code debugging information from the executable binary files of programs being debugged. Each compiler uses its own method for encoding debugging information, and the compiler's associated debuggers work with those unique formats. Quincy 99's debugger extracts and interprets the stabs debugging tokens that gcc encodes. Designing and implementing that process was one of the most difficult parts of building Quincy, not only because it is an inherently complex process, but also because the only thing more abstruse than the stabs format itself is the documentation that describes it (http://people.redhat.com/ johnsonm/lad/info/stabs.html). The stabs expert programmer for Cygnus, the company that leads the gcc development project (now part of Red Hat), once answered one of my questions with the observation that having developed a stabs-based debugger, I probably knew more about stabs than he did. The stabs format is more complex than other debugging formats because stabs is designed to be portable across languages and platforms.
Not only do I not want to repeat the work of building a different parser for a different debugging information format, I do not want to have to reverse engineer the format itself, which is not documented, by poking around in the cryptic segments of executable binaries. Been there.
Inprise's release of the free BCC32 compiler met with a barrage of complaints from programmers because BCC32 does not include a debugger. Well, Inprise answered, there is no command-line debugger to release, at least not one that works with BCC32's proprietary debugging information format. The old Turbo Debugger is a 16-bit program that is incompatible with the 32-bit executables that BCC32 generates. They're not about to release its GUI debugger because it is an integral part of the C++Builder IDE.
Borland responded to both concerns -- my unwillingness to do another debug information excavation and programmers' complaints about the unavailability of a compatible debugger -- when they released an API specification and DLL for extracting the debug information from executable files compiled by BCC32. You can download the API definition in the form of a C++ header file and the DLL from http://ww6 .borland.com/codecentral/ccweb.exe/ listing?id=14513. Inprise said, in effect: You want a debugger? Use these tools and write one for yourself. It's not exactly the best solution for all developers but it offers a significant advantage for veteran debugger builders. The API is a high-level encapsulation of the hairy details of debugging information retrieval and interpretation. All the stabs-related analysis and development work I did for Quincies 96, 97, and 99 -- understanding the stabs format, understanding executable file formats, reading the executable file, finding the debug information segments, reading the debug information, parsing it, translating it into tables usable to the debugger, and so on -- is replaced for the BCC32 format by a relatively simple high-level API. I say, "relatively simple." It ain't no walk in a rose garden. But it's a lot easier than doing it for yourself.
My first obstacle to this upgrade was one I unintentionally built four years ago. The Quincy 99 debugger and its ancestors use the public interface of a class that encapsulates all stabs processing. Although the public interface is generic, it is still an integral part of the stabs class I designed. In other words, the design does not anticipate that Quincy might someday support a different compiler. Consequently, the first part of this upgrade involves some fundamental object-oriented redesign and reprogramming. There must be an abstract base class that implements the debugging information's public interface. Classes that implement the details of debugging information for different formats will derive from the abstract base class. The first such derivation is the one that implements the stabs format. Or perhaps it should be done with a template. Or an embedded object. To be decided.
Debugging information in an executable file describes the source code and the data types of the program. It specifies, among other things, where the debugger should find the source-code files during debugging, intrinsic types the language supports and user-defined types that the program defines, the line numbers of each source-code file that correspond to executable statement addresses, the addresses of functions, symbols that name objects, the scope in which objects are declared, and the addresses of the objects. Debuggers use these data to form debugging information to implement source-level debugging. A debugger loads that information into memory and uses it to step through the program, display and modify the memory contents of variables by name, set and intercept breakpoints, and so on. C++ includes complexities that other languages do not have -- namespace qualification, function name mangling, huge template names, and so on. The abstract base class (or template, or whatever) that provides the interface to these data values must be independent of any specific implementation of debugging information, be it stabs, COFF, the BCC32 format, or whatever.
There is more to a debugger than extracting debugging information from the executable file. The debugger has to do something with the information, stepping through the program, setting and watching for breakpoints, examining memory variables. Most of that part already works in Quincy and is unlikely to change much. I say that, but nothing is certain when you are dealing with debuggers. The original version of Quincy used the old gnu-cygwin port of the gnu C/C++ compilers, which was always in beta through at least 18 major version releases. Every time they released a new version, Quincy's debugger failed. I stopped upgrading with Version 10 because I couldn't keep up and had to release something for my CD-ROMs.
Adapting BCC32's debugging information is only part of the upgrade. The make and compile/link processes, which are command-line tools, are launched by the IDE and, of course, Quincy 99 is gcc-centric. Another higher level generic interface class is called for to manage those things so Quincy 2000 can work with either compiler or even a third one at a later time. I'll build this interface before tackling the debugger. It might seem a simple task, but, if the gcc experience is any indication, there are thorny issues in store when you integrate command-line tools with a GUI IDE. Read on for a brief mention of one of them.
I warn you now that Quincy 2000 is vaporware. About a year ago, I announced, so to speak, something called D-Flat 2000, which was to be a GUI application framework developed with Quincy and based on the abstraction mechanisms of Standard C++ and the Standard C++ library. I postponed its development until there was indeed a free Standard C++ compiler to build it with, and that has not yet happened. Until now. Maybe. These plans can vanish into the vapor just as D-Flat 2000 if I cannot make Quincy's BCC32 upgrade work. Something simple like not being able to capture the compiler tools' error messages into the IDE could spell the project's demise. I went through much grief getting that one small feature working with Quincy 99, gcc, and Windows NT.
Inprise released this free BCC32 compiler to stir interest in its commercial C++Builder development products, a laudable and forward-looking strategy. Quincy 2000, if it turns out to be a viable project, can provide lots of exposure to that strategy. If someone from Inprise reads here or at their online site that I am having a problem, helping me solve it might be a good idea. Hint, hint.
On the other hand, that stabs expert from Cygnus a while back wondered if he should be all that helpful with my gcc debugger. After all, he said, I was developing a competing debugger to their venerable gdb. In this case, I am developing a competing development environment, and it's going to be free -- if it ever descends out of the vapor, that is.
And now, for the rest of the story. (I've always wanted to say that.) Six hours after I wrote the opening paragraphs of this column, a tire service truck rolled up.
I explained what happened to the tire technician. He shook his head, pulled off the blown tire and showed me a big 15-inch smile of a split in the inner sidewall. "You're a really lucky guy," he said. "If this had blown on the outer sidewall it would have killed you. See how it disintegrated all this sound proofing in the wheel well and blew off that access panel? Seventy pounds of air forcing its way out this split all at once? It would've blown you clear out to the Interstate. Probably would have taken your head plumb off." He seemed to enjoy telling me all this stuff.
DDJ