Showing posts with label Compiler. Show all posts
Showing posts with label Compiler. Show all posts

Tuesday, July 08, 2008

Still time to enter the Darwin Race of Languages

Do you think that hand tweaked C code runs circles around managed code (C#, Java, VB.NET)?  Or do you think that your Just In Time compiled managed code gets the job done more securely than those bit sniffing dinosaurs?  Anxious to prove that Delphi is still relevant?  Want to win some cutting edge component libraries from DevExpress?

If you answered “yes” to any of those questions, there is still time to enter the Darwin Race of Languages.  The brainchild of Sevensteps CTO Bart Roozendaal, the Darwin Race is pitting a slate of challengers using the compiler and IDE of their choice to write a utility that will solve one of three problems.  The projects are the following:

  • Temperatures and CPU load
    A utility that will measure CPU temperatures and CPU load on remote computers
  • Multi clipboard utility
    The utility should hold several entries that were place on the clipboard earlier. In effect it should replace the clipboard.
  • GUI to a command line program
    A GUI front end for the gbak database command line driven program for the Firebird database.

Each entry will be judged on the software itself and how you documented the design and development of the application.  The goal is not to see which development is best tool, but to see what tools are the best for different types of jobs.  To see where the strengths are and where are the weaknesses of each tool, using real world types of the problems.  The documentation part will share the development process and show how different people come up with solutions for similar problems.

There are already a bunch of sponsors lined up.  DevExpress will be giving away a a license for DXperience Enterprise or the VCL Subscription.  If you wint, you get to pick one of them.  I have DXperience and most of the VCL components, you can’t go wrong with either one of them.

The race is on already, but there is still time to join.  There are a bunch of participants already signed up, covering C#, Delphi, VB, and something on the Mac platform.  Java is not yet represented, does someone out there want to pick up the Java gauntlet?

Monday, April 07, 2008

Fun with CoInitialize

I was tracking down a error in one of the command line apps that I use to save web.config settings over upgrades.  It was a strange error, If I stepped through the code, everything executed correctly, but I would get an access violation when I left a specific method call.  The fun part was that all of the code in that method call executed normally.  The app is written in Delphi 2007 and is Win32 unmanaged code.  The code looked something like this:

function TSaveConfig.UpdateWebConfig(const srcfile, destfile: string): boolean;
var
fsrcDoc, fDestDoc: IXMLDocument;
begin
CoInitialize(nil);

result := true;

fsrcDoc := LoadXMLDocument(srcFile);
fDestDoc := LoadXMLDocument(DestFile);

UpdateNode(fsrcDoc, fDestDoc, 'configuration\system.web\httpRuntime', 'executionTimeout', '', '');
UpdateNode(fsrcDoc, fDestDoc, 'configuration\system.web\sessionState', 'timeout', '', '');

if fDestdoc.Modified then begin
fDestdoc.SaveToFile(DestFile);
end;

CoUninitialize;
end;



Not much to it.  My Spidey sense started tingling at the calls to CoInitialize/CoUninitialize.  CoInitialize is needed to initialize the COM library on the current thread.  And COM is needed because I am using MS XML COM objects to work with the web.config files.  I was initializing COM, using COM, then uninitializing COM.  The problem was that I was using interfaces to the COM objects and Delphi is managing the lifetime of interfaces.  At the end of the method call, those objects go out of scope and Delphi calls their cleanup code.  In my case this happens after the the call to CoUninitialize.  My IXMLDocument interfaces were being garbage collected by the Delphi runtime and they were referencing a COM library that had been already closed.


In this case, the fix was easy.  I just moved the calls to CoInitialize/CoUninitialize to the code that calls UpdateWebConfig.  Once I did that, my odd little access violation was fixed.  That's one of those bugs that seems obvious after you fix it.  What clued me in to what was going on was a post by Chris Bensen that explained it all.  Thanks Chris!

Tuesday, March 11, 2008

The Lost Art of TSR Programming

Scott Allen had a amusing post, "Talks You Won’t See At the Local Code Camp", on his blog.  One of the talks was "The Lost Art of TSR Programming".   That shook some memories out of the cranial storage device.  I used to write TSR programs, more formerly known as Terminate and Stay Resident.

This takes back to the days of DOS, when giants like dBase and Lotus walked the land.  Your network was Novell and you feared the Bindery.  You could only run one program at a time and the 640K limitation was real and not just a saying commonly misattributed to Bill Gates.

When I was at Stochos, we wrote software to do statistical process control (SPC) in the manufacturing industry.  We would collect data from measurement devices or from the manufacturing hardware to monitor the process of making whatever was running.  Back in the late '80s, we had hardened PC's running DOS and our software right on the factory floor.  One of my tasks was to write the code to collect the data from the machines and get it into the PC.

Early on, I had decided that the data collection code would run separately from the SPC application.  This allowed the user to exit our app to run other apps while still collecting data.  The way I did that was to write the data collector as a TSR.

The whole TSR section of DOS programming was pretty much an accident.  The DOS print spooler gave DOS the ability to print in the background while your application was running.  The print spooler was the first TSR.  A TSR would load itself using INT 27H to make itself as a TSR type of programming.  Once loaded, the TSR would typically insert itself into the chain of the applications that would receive hardware and/or software events.  If the TSR wasn't careful, it could wreck havoc with the interrupt chain.

I would write TSR's that would hook into the serial port or parallel port events.   Some of the time, all I needed to do was to capture data as it came in and write it to a file.  Usually, the hardware would have some sort of protocol and I would have implement it in my code.  One of the odder ones was for a machine that printed foil packets, the kind used for condiments at fast food restaurants.  This machine did not support the logging of it's data.  But I found a way in.  It had a PC that functioned as operator console with a color screen and keyboard.  Usually the screen would be displaying the current process settings and readings from it's own measuring devices, but not always.  The PC was connected to the machine over the serial port and was basically being used as a terminal.

I wrote a TSR that would periodically scan the screen in memory.  Since it was running in text mode, it's fairly easy to ready the screen from memory.  If I saw a certain sequence of characters at a specific location, I knew that I had the main console screen.  I then scanned different locations on the screen and wrote out a text file, logging each set of values as an attribute for our SPC application.

The TSR would read a template file that listed what attributes to look for and at what locations on the screen to expect the attributes at.  The setup of the template was done by trial and error, but once it was set the client never had to touch it.  It even allowed for character translation.  For some odd reason, the console display didn't use the number "0", they used the letter "O".  That took more time to track down then you would have expected.

To keep the size of the TSR down, I used a library named CodeRunner with Microsoft C.  The Coderunner library had the housekeeping code for doing the INT 27h stuff and interrupt managing.  It also took many of the standard routines and replaced them with hard coded assembler optimized for space over performance.  It also had the ability to run most of the TSR out of EMS memory, greatly reducing the footprint in the lower 640K space.  This particuliar TSR took about 6000 bytes of conventional memory.  I remember talking to Ratko Tomic, the engineer who wrote the CodeRunner libraries.  He was genius at squeezing every extra byte of the TSR code.  It's a lost art.

Monday, March 10, 2008

I like having a build box

This morning I came across a blog by Landon Dyer called Dadhacker.  He got linked by BoingBoing for a entertaining post that he wrote about working on the Donkey Kong cartridge for Atari.  I started reading his other posts and it turns out that I agree with nearly all of his opinions.  Except for build boxes. He wrote:

The best thing you can do for your productivity when you’re tempted to set up that spare machine to do extra work for you is to ditch the thing.

If you are the person only using that build machine, I can see that point.  Almost.  I would argue that it's worth the time to have a 2nd machine in case the first one goes to the land whre DOS is eternally blessed.  For a team of programmers, having a dedicated build box is a must have feature.  No more guessing which program set which option to build which executable, they always get built the same way.  Plus it offloads the build process processing from your development environment and that is always a good thing.

The other advantage to having a dedicated build box is that you have have it do everything.  We use FinalBuilder and it's the kitchen sink of automated build tools.  We build about a half dozen or so shrink wrap ready applications on our build box and they all pretty much follow the same pattern:

  1. Get the latest code from source control
  2. Read an .ini to get the version number and other test resources, the build tool will bake the version number into the compiler and install builder.
  3. Compile the application
  4. Collect all of the bits and put them in a folder for the install builder
  5. Authenticode anything remotely executable that we compiled
  6. Create the installer from all bits that were compiled in the last step and add the necessary required bits (CaptiveX controls, Assemblies, help files, etc).
  7. Copy the installer to a deployment folder for QA to test
  8. Send an email to QA and other interested parties that a new build was available and include a change list in the email.

There are other minor tasks that get performed, but that's the gist of it.  And it works for for Delphi Win32 and .NET assemblies, with error handling.  The time our department saves that level of build automation clearly outweighs the the maintenance time on the build box.