On April 29, I made an inquiry to this forum about an odd OS 3.5 
problem, about which I have since discovered a fair amount, 
particularly with some help from Ken Krugler of TransPac 
Software, Inc.  I haven't found anything on this in the Knowledge 
Base, and no one from Palm has commented on it, but I'd like to 
post some information here about a workaround for what is 
evidently a bug in Palm OS 3.5, as that platform is still widely 
used and others are likely to run into this.

The problem manifests as memory corruption that occurs during 
closing of a form under particular circumstances.  As far as I 
know, it only occurs when the system is operating in 
4-bit-per-pixel mode, though my understanding of the reasons 
don't explain why that should be the case.  I've only seen it 
occur when another application is sublaunched twice on top of a 
form in the main running application, though I don't know if 
that's actually a requirement.

The problem is a bug in the Palm OS 3.5 bit-blit module.  The 
blit setup code sometimes needs to create a color translation 
table for the operation at hand, and at other times it can used a 
"canned" color translation table.  In both cases, the table 
resides in an allocated memory chunk; but in the first case, the 
table is temporary and needs to be released at the end of the 
operation, whereas in the second case, it is permanently 
associated with the current screen mode, and should not be 
released at the end of the operation.  The bug is that the 
"canned" table is sometimes mistakenly released at the end of the 
operation, resulting in a dangling global pointer to an 
unallocated memory chunk.

The symptoms are varied; on an emulator, the commonest is the 
message "<application name> just wrote to memory location 
0x........, which is in Memory Manager data structures."  A heap 
dump taken by the Palm Console at this point will typically 
terminate with the message "#ERROR: Invalid Handle field".

The workaround takes cognizance of the logic used by the blit 
code to determine whether it needs to allocate and build its own 
color translation table.  The bug can be prevented if the 
destination bitmap in a blit operation which would otherwise run 
afoul of this problem is given a color table with at least one 
entry.  In my case, the destination bitmap was the "bitsBehind" 
bitmap of a form, used for restoring the form after another 
window has been drawn on top of it.  You add the workaround code 
to the handler for frmOpenEvent; what it does is replace the 
(newly opened form's) saveBehind bitmap with another bitmap which 
has a color table.  It goes like this:


     if (!palmOSLessThan35() && palmOSLessThan40()) {

         FormType* pForm = FrmGetActiveForm();
         WinHandle hBBF;         // "bitsBehind Form"
         BitmapType* pBBBM;      // The bitmap owned in hBBF
         UInt8 depth;            // The depth of pBBBM

         if ((hBBF = pForm->bitsBehindForm) != NULL && // ***
             (pBBBM = WinGetBitmap(hBBF)) != NULL &&
             (depth = BmpGlueGetBitDepth(pBBBM)) == 4)
         {
             Coord width, height;
             BmpGlueGetDimensions(pBBBM, &width, &height, NULL);

             int colorTableEntryCount = 1 << depth;
             ColorTableType* pColorTable = 
(ColorTableType*)MemPtrNew(
                 sizeof(ColorTableType) +
                 colorTableEntryCount * sizeof(RGBColorType));
             pColorTable->numEntries = colorTableEntryCount;
             Err e = WinPalette(winPaletteGet, 0, 
colorTableEntryCount,
                 ColorTableEntries(pColorTable));

             BitmapType* pNewBitmap = BmpCreate(
                 width,
                 height,
                 depth,
                 pColorTable,
                 &e);
             MemPtrFree(pColorTable);

             if (pNewBitmap != NULL && e == errNone) {

                 //  Jam the new bitmap into the window structure in
                 //  place of the old one:
                 //
                 hBBF->bitmapP = pNewBitmap;     // ***
                 BmpDelete(pBBBM);

             } else
                 ASSERT(false);
         }
     }


The main trouble here is that the lines marked with "***" will 
cause complaints from the Emulator, since they perform direct 
accesses to UI Manager memory structures.  These complaints can 
be suppressed by unchecking the box "UIMgr data access" in the 
Emulator's debugging settings panel.  Which is unfortunate, as 
the checks being suppressed often turn up real bugs in 
application code.


Greg Lutz
NearSpace, Inc.


-- 
For information on using the Palm Developer Forums, or to unsubscribe, please see 
http://www.palmos.com/dev/support/forums/

Reply via email to