>-----Original Message-----
>From: Richard Bram [mailto:[EMAIL PROTECTED]]
>Sent: Tuesday, June 01, 1999 9:51 PM
>To: [EMAIL PROTECTED]
>Subject: Dynamic trap patching
>
>
>What is the safest way to do my own dynamic trap patching and
>unpatching? (Yes, I know, "don't do it!").

Don't do it! (couldn't resist)

>Anybody got any simple (or complicated) ways to avoid conflicts with
>other hacks that might simultaneously be patching the same traps?

There are two pretty nasty problems that you probably already know about,
Rick.  I'll reiterate them for anyone who hasn't had fun with this stuff
already.

Say you do this: 
        pOldEvtGetEvent = SysSetTrapAddress( sysTrapEvtGetEvent,
MyEvtGetEvent );

As long as MyEvtGetEvent() calls through (in this case, before it does
anything else) to pOldEvtGetEvent, you will be ok with this.  When your app
is exited, you start to see the nasty problems.  Nasty problem #1, the
function address you stuffed in as the second argument to that
SysSetTrapAddress function probably isn't valid any longer.  If you happen
to Menu:Delete the PRC, it's _definately_ not a valid address.  We all know
what happens when the OS jumps to an invalid address!

Nasty Problem #2 occurs when you realize Nasty Problem #1, and to try and
fix it you do this in AppStop by restoring the old function pointer to get
yourself out of the loop:
        SysSetTrapAddress( sysTrapEvtGetEvent, pOldEvtGetEvent );

The problem here is if anyone else came along somehow behind your back and
did their own SysSetTrapAddress( sysTrapGetEvent, TheirEvtGetEvent ), you've
just hosed them because now TheirEvtGetEvent() suddenly ceases to be called!
Who would be diddling with traps behind your back?  I dunno, maybe like an
app sub-launched because of a 'find', or maybe a custom netlib interface
running in the NetLib task that needed that trap, who knows.

Here's one solution.  

Wrap your MyEvtGetEvent() function into a shared library, load that library
before your SysSetTrapAddress (if it isn't already loaded!), and just never
unload it.  Now, your app can safely do its SysSetTrapAddress(
sysTrapEvtGetEvent, MyEvtGetEvent ).  MyEvtGetEvent exists in the shared
library, so that's fine and dandy.  When your app exits, the shared library
is still hanging around, so Nasty Problem #1 goes away.  You've also walked
around causing Nasty Problem #2.  The expense of this solution is a little
bit of wasted memory for your shared library (and the fact that now, your
app needs to distribute with an additional PRC that contains this shared
library, the user has to install it, etc).

When the Palm gets a soft- or hard-reset somewhere down the line, your
shared library will FINALLY get unloaded from memory and the code resource
of MyEvtGetEvent() will go away.  This is fine, because when you reset the
device, all of the trap addresses are restored to the stock OS trap
addresses anyway.

Here's another solution I just though of.  If you could allocate a chunk of
memory at runtime, MemMove the code of MyEvtGetEvent() into that memory
(store it as a resource in your PRC?), and MemPtrSetOwner ( pMyEvtGetEvent,
0 ), that memory won't go away until you reset the device.  '0' means the OS
owns that memory, so hands off, PalmOS garbage collector.  Shame on you,
though, for permanently wasting heap!  You could probably just lock down a
storage heap chunk and do the same thing.  The expense here would be you
wasted some storage heap (not really a huge problem) and you can never
unlock that chunk, so you kind of fragment memory a little bit.

Just some food for thought.  Any input, Palm people?
-Jeff Ishaq
The Windward Group

Reply via email to