Monthly Archives: June 2010

Barracuda Attack

Like the song’s antagonist, one of my two Barracuda 7200.12 1 TB hard drives just became a real low-lying nuisance.  Yesterday, my four-way Windows 7 box grew incredibly sluggish, a problem which persisted over restarts.  With the case cover off, I could hear intermittent clicks and buzzes coming from the primary hard drive.  They weren’t the extreme clicks of death, but sounds that seemed to indicate stumbling over chunks of bad sectors.

This was one of those once-every-year-or-so moments when backups go from pure overhead to the greatest thing since the ten cent gigabyte.

I suppose there are as many backup strategies as there are computers.  Components of this strategy balance the trade-offs between redundancy and recovery time, with RAID-1 or RAID-10 at one end, and incremental backups of just the personal data at the other.  I’ve gotten out of the RAID-1 habit for a few reasons: consistency with laptops, bad experiences with “logical” data failures (if you corrupt a Windows registry hive, you’ve just backed up the problem), and problems with lower-end RAID controllers.  But for my quick recovery needs, I do perhaps the next closest thing: put in pairs of drives and use periodic imaging and regular XXCOPY script runs (with /CLONE) to keep them in sync.

Because of this, recovery was indeed quick and easy; I simply swapped my shadow hard drive to primary and restarted.  This took the bad drive out of the critical path so I could find out what was wrong, and perhaps RMA this thing that I’ve only had for six months.

A full chkdsk found no bad sectors, and the SMART stats were within thresholds (with SMART, the absence of bad news is not necessarily good news).  Confounded, I let HD Tune run a full error scan.  It reported no bad sectors, but I could again hear the clicks and buzzes at various points: around 250 GB, 300 GB, 568 GB, 596 GB, and 695 GB.

So maybe this drive is farther from full failure than I thought.  But I’m not taking my chances, especially given Seagate’s checkered past with drives in this line.

Ironically, on the same day of the failure, I received a TigerDirect email offering this exact drive for $69.  Pass.

I Ignore Your Puny 32 Bits

Customers these days: they think they’re entitled to 64 bits.  Heck, I remember when we had to do everything with just 32 bits, and only half of those worked.

Since 64-bit Windows and Linux are the new normal, the DB2 LUW folks (particularly with 9.7) have been encouraging migration away from 32 bit apps and libraries.  Sometimes this is more than a gentle nudging, as things break and require intervention.

Colleague Allen Cartright shares a tip for managing 32-bit ODBC data sources when 64-bit Windows just wants to ignore them.  So, if you find yourself running 32-bit DB2 code on a 64-bit OS written by a 2-bit company that can’t stand 1-bit of competition, heed his advice:

The ODBC connection manager in Windows Server 2008 (Administrative Tools -> Data Sources) is 64 bit only.  To get to the 32 bit ODBC connection manager in Windows Server 2008 Rx x64 you must run the executable directly as there aren’t any icons for it.  The executable is “C:\Windows\SysWOW64\odbcad32.exe”.  This is the same executable name as the 64 bit version but is in the legacy directory.  Once you have the 32 bit version of the ODBC Connection Manager open you may add the ODBC connections as normal.

The Microsoft Knowledge Base post on this has additional information and recommends a useful naming convention:

To work around this problem, use the appropriate version of the ODBC Administrator tool. If you build and then run an application as a 32-bit application on a 64-bit operating system, you must create the ODBC data source by using the ODBC Administrator tool in %windir%\SysWOW64\odbcad32.exe. To indicate the type of DSN, you can add “_32” to the 32-bit user DSNs and “_64” to the 64-bit user DSNs.

Between the Lines

Today I was asked for some quick help with additions to a customer’s C++ code running as a user exit in one of our systems.  This bit of code used sprintf to format an error message into a buffer passed in by our system.  Pretty pedestrian stuff, but it came among many surprises, one being that the code often had no regard for buffer lengths, and risked overflowing them.

The buffer was only 256 bytes because it’s used for a summary message (if there’s more to say, it should be said elsewhere, such as a log file).  256 bytes is pretty easy to overflow, particularly with additions we added, so we needed some crash protection.  snprintf would have been a quick alternative, but was not available on this platform.  So I added widths to the format specifiers, changing something like this:

sprintf(pszMessage, “SQL error in whatever, rc=%04d, SQL=%s”, rc, pSql->Stmt);

to this:

sprintf(pszMessage, “SQL error in whatever, rc=%04d, SQL=%.215s”, rc, pSql->Stmt);

To avoid magic numbers, I could have done something like:

sprintf(pszMessage, “SQL error in whatever, rc=%04d, SQL=%.*s”, rc, (BUFFER_SIZE – 40), pSql->Stmt);

And had snprintf been available, it would have been even cleaner:

snprintf(pszMessage, BUFFER_SIZE, “SQL error in whatever, rc=%04d, SQL=%s”, rc, pSql->Stmt);

Truncating a message is not ideal, but it sure beats tossing a GPF.  In this case, losing the end of the SQL statement would not be a big deal, but the message could be rearranged or additional logging added if it were.

The point is that too much C and C++ code in the wild holds too little concern for bounds checking.  Fortunately, I now code mainly in OO languages where this is not a concern – things grow as needed.  But since C and C++ (taken together) are still arguably by far the most pervasive programming languages (with new programmers on board with it every day), it’s very much relevant.  The advice is simple:

Avoid unbounded string functions.  Avoid sprintf, strcpy, strcat, strlen, and gets.  Use snprintf, strlcpy, strlcat, strncpy, strncat, fgets, and similar functions depending on availability.  If these alternatives aren’t available, use techniques like the above to avoid overflowing buffers.  When using the strn functions, remember to leave room at the end to add the null terminator (and remember to add it!)

You can find further such advice in the C Programmer’s Ten Commandments.

Back in the day, when I coded mostly in C and C++, we augmented our lint process to scan for things like strcpy, strcat, and sprintf.  Richer compiler warnings have largely taken the place of lint (with extensions lost along the way), but it’s easy enough to simply grep for these.  And the time spent staying between the lines is a small price to pay for some crash insurance.

The Friday Fragment

It’s time again for the Friday Fragment: my weekly programming-related puzzle.

This Week’s Fragment?

I caught a little grief for inflicting Lisp on readers last week.  So I took that (along with sunny evenings, good river water levels, race targets, and a poolside reading list) as a sign to give the Friday Fragment a summer break.  I have some ideas for new types of challenges when we pick it up again, so look for its return in the fall.  Until then, enjoy the summer!

Last Week’s Fragment – Solution

Last week’s fragment was a challenge to think inductively and recursively:

Code a factorial function (s-expression) in Lisp or Scheme.  For example, (factorial 3) should evaluate to 6.  Include unit test scaffolding code.

As mentioned above, the response to coding in Lisp/Scheme wasn’t positive.  One comment I got was “I’d rather write Esperanto poetry”  (kids these days, can’t think outside the box).  So I was left to code this one on my own.  Here’s my implementation:


   (define factorial
         (lambda (n)
             (cond
                 ((< n 0) "n must be non-negative")
                 ((= n 0) 1)
                 (else (* n (factorial (- n 1)))))))

 

My test/scaffolding code is:


   ; Unit test case helper:
   (define test
     (lambda (x y)
       (cond
         ((equal? x y) "pass")
         (else (list "FAIL - expected: " y " but got: " x)))))

   "Factorial unit tests"
   (test (factorial -1) "n must be non-negative")
   (test (factorial 0) 1)
   (test (factorial 1) 1)
   (test (factorial 3) 6)
   (test (factorial 55) 12696403353658275925965100847566516959580321051449436762275840000000000000)

 

I used Dr. Scheme (PLT Scheme) for this, which (like most functional programming environments) is optimized for tail recursion.  So even large factorials run fast without error.  By comparison, recursive factorial functions in C and Java will (depending on argument size, stack size, and/or VM) either take forever or fail with a stack overflow.  One solution for these more traditional environments is to convert tail recursion to iteration and avoid the "stack attack" of recursive function calls.

Battling Droids

Given recent questions about my Droid phone, perhaps it’s time to post again about it.  This time, I’ll offer tips on battling two common Droid demons.

1. The condensation poltergeist. The tiniest amounts of condensation can make Droid’s touch screen act possessed.  The Ghost of Droid will scroll automatically, start apps, search for things, make phone calls, and wreck all sorts of direct-manipulation havoc.  And there’s no point in fighting it: it’s much faster than you, and when it takes over, it’s usually impossible to win the battle and override it.  A locked screen offers some protection against emailing your boss or calling Tokyo without your consent; in this case, it can only repeatedly try to draw out your unlock pattern, usually resulting in a series of “wait 30 seconds” holds.  It’s entertaining to watch, but annoying to say the least.

This weird phenom has been ascribed to viruses, chargers, and other hardware and software issues, but, in my experience, it’s always due to condensation on the touch screen.  And since it requires so little moisture, it’s hard to predict when it will happen.  It has happened to me upon walking into an indoor pool area, and inside my car after a long run.

As long as you keep your Droid at 70 degrees and 40% humidity (perhaps in the raised floor area of your personal data center), you’ll be fine.  For those of us in the real world (and who like Georgia summers), just stop using it when it happens, turn it off, be patient, and wait for it to dry out.  You can help it along by bringing it back into the air conditioned indoors or using a blow dryer on a cool setting.

2. The grim reaper ringer. That “slide to answer” control and dexterity test works great at preventing accidental unlocks and butt calls.  So great that if you try it while driving, you’re as likely to annihilate as answer.  An early Android update made it slightly easier (straight rather than curved slide), but it’s still difficult.  Most bluetooth headsets provide an alternative, but if you’re not headsetting it, it’s best to just pull over before attempting to answer, or simply miss the call and return it later.  Answering that call is not worth crashing into the ditch or oncoming traffic.

I’ve heard that the latter problem will be fixed soon in an Android (software) update, but the touch screen issues will probably have to wait for a new phone (gotta love “new every two”).  My next phone will almost certainly be an Android, but probably won’t be a Motorola Droid.

The Friday Fragment

It’s Friday, and time again for a new Fragment: my weekly programming-related puzzle.

This Week’s Fragment

With this week’s fragment, we’ll start a series of puzzles to code something in a specified language.  The code itself won’t be difficult, but it will highlight the unique benefits of a particular language (or, in some cases, recently-added features to a language).  It’s your chance to try out a new language or feature.

Will start by thinking inductively and recursively, and that’s where functional languages like Lisp/Scheme shine.  This is a “classic” exercise (meaning there are probably a million solutions posted on the web), but try it yourself before peeking.  The problem is simple:

Code a factorial function (s-expression) in Lisp or Scheme.  For example, (factorial 3) should evaluate to 6.  Include unit test scaffolding code.

For extra credit, code a recursive factorial function in a more mainstream language (like C or Java) and compare the performance/results to Lisp when taking the factorial of a very large number.  There are several free Lisp/Scheme implementations you can use; Dr. Scheme (PLT Scheme) is one good choice.

To “play along”, post the solution as a comment or send it via email.   To avoid “spoilers”, simply don’t expand comments for this post.

Last Week’s Fragment – Solution

Last week’s fragment was sent in by Joel Odom:

Write C code or pseudo-code to swap the values of two integer (int) variables, a and b, without declaring or using any other variables. Do not use any syntactical language tricks that implicitly copy values out of a or b into other memory or registers.  You can use C operators, control flow, and similar statements.

I was left to solve this one on my own, and sent Joel two solutions.  For the first, I used the wonders of XOR.  Among other things, XOR’ing something with a value twice gets the original value back: a feature used for simple bitmap animation, masking, encryption, etc. – and it’s fast.  For the second, I called a function, using the stack to push/pop one of the values.  Joel approved the XOR approach, but said the function call was cheating since it allocated memory on the stack (good point).  Here’s the simple XOR solution; for the function call and scaffolding code, see comments to last week’s post.

a=a^b;
b=b^a;
a=a^b;

Defaulting Less Security

Today, a friend reported that one of the apps I provide as a community service was down.  Its WebCalendar component complained that magic_quotes_gpc was no longer enabled, which I quickly confirmed by dropping in a phpinfo() call.  The remedy was also quick and easy: add a local php.ini with:

magic_quotes_gpc = On

This automatically adds slashes to escape quotes and other characters in GET, POST, and Cookie strings (hence “gpc”).  The PHP code then removes these via stripslashes and similar techniques.

Magic_quotes_gpc is no longer considered a good way to guard against SQL injection attacks, so the PHP Security Consortium and others now recommend against it.  I suspect this is why my hosting service changed their global setting to off, but security-wise, that was a step in the wrong direction.

Many PHP apps that support magic quotes are coded to work even if it’s turned off, and the get_magic_quotes_gpc()  ? stripslashes template for doing this is seemingly everywhere.  Fortunately, WebCalendar checks for this, but many apps don’t.  Disabling magic quotes was probably done to force apps to change, but it’s more likely apps will continue to work and developers and admins won’t realize that they are suddenly far more susceptible to injection attacks.  A better approach would have been to just let it die with the 5.3 upgrade.