Hi,

For the sake of the archives, I'm closing this thread with a summary of the conclusions. This is a long post, and has nothing new for those who've been following the thread.

The Problem

I was getting a 'Privilege violation' when closing some apps, after running a Desk Accessory (DA) I was writing. The Desk Accessory ran fine, the application seemed to run fine too, but when I tried to close the application, the Palm would issue a 'Fatal Error' which MW debugger identified as a 'Privilege Violation'.

Diagnostic

The problem was correctly traced by Steve Lemke to the use of global variables by my DA.

DA launchers do not allocate the space for global variables. The compiler doesn't know that, and assumes the global space will be allocated. When I used global variables, without allocating space for them, I was unknowingly using the running app's global space, possibly corrupting data. This is consistent with the observed behaviour.

The solution

Knowing that no global variable space is allocated for the DA, I still needed some kind of global variables on my code.

Three possible solutions emerged, presented by my preference order:

  1. Mimic the PalmOS global space allocation. This would ideally be done by the DA launcher, but can be done by the DA itself.


  2. It involves allocating the space for the global variables, and setting the A5 register upon startup. Upon cleanup, reverse the process: Free the allocated memory and restore the A5 register.
  3. Use FtrSet and FtrGet to save and retrieve a pointer to a structure holding all the global variables. Although this solution works, I don't like it as much because it prevents using software components (like gadgets), that assume the availability of globals.
  4. Use one global pointer to a struct holding all the globals. In this struct, save the old value for this pointer, so you can restore it upon cleanup. This solution has all the drawbacks of the previous one, plus the assumption that there is space for one pointer in the running app's global var space. It is unlikely for this assumption to be false, but possible.
Appendix A - Global variable allocation in PalmOS

Since the documentation for DAs does not include this type of explanation, I will reproduce the post by Douglas Anderson. It may be incomplete, or have minor errors, but it provided enough explaining for me and my problem.

In PalmOS, space is allocated by the OS for an application's global
variables.  As has been pointed out, this happens when an application
starts up normally (though it doesn't happen with some launch codes).
PalmOS then lets applications access this chunk of memory by placing a
pointer to it in A5 (if I recall correctly, A5 points just below the block
of memory).

The memory that has been allocated is for the application to use however it
wants.  The operating system won't clobber it, and if PalmOS is ever
designed to run more than one user application at the same time, it would
have to make sure to allocate lots of separate globals spaces and change
the value of A5 each application switch.

Now, let's look at the compiler.  The compiler knows that the OS has
allocated this big jucy chunk of memory that can be accessed relative to
A5.  That's where the compiler is going to put its globals.  As I've said,
this block of memory is owned by the running application.  Thus, the
compiler can divy it up as it sees fit.  The compiler does this "divying"
at compile time.  It knows about all the globals in the application and can
decide where all of them go.  Thus, a reference to a variable called
"gResult" might be placed _at compile time_ at -16(A5), depending on how
many other global variables were present in the app.  Remember, since the
compiler knows that nobody else will be screwing with this memory, it can
decide what locations it wants to use and just hard-code them into the
final binary.

Now, let's imagine writing a desk accessory, where (as we have been told),
a new globals space is _not_ allocated when the desk accessory launches
(the same is true of hacks for you hackers out there).  First, we compile
our code resource.  The compiler, knowing of the PalmOS's convention for
using A5-relative globals, will figure out how many globals we have in our
DA and then allocate space for them relative to A5 (at compile time).  As
it knows about "all" the globals, it can pick whatever locations it wants
to store something (as long as it's in the OS'es block).  Let's say it
picks -16(A5).  Now, we run our DA.  The application puts something
-16(A5), knowing that nothing else is going to be clobbering it.  Then, the
DA gets launched.  Note that A5 hasn't changed, as DA's don't get their own
globals space.  The DA now stores something -16(A5), thinking it has its
own globals space.  Oops!


My thanks to:

  • Richard Hartman <[EMAIL PROTECTED]>
  • Steve Lemke <[EMAIL PROTECTED]>
  • "Douglas I. Anderson" <[EMAIL PROTECTED]>
  • Ivan Shiyan <[EMAIL PROTECTED]>
  • Jason Dawes <[EMAIL PROTECTED]>
  • David Fedor <[EMAIL PROTECTED]>
References: --
Sergio Carvalho
---------------
[EMAIL PROTECTED]

If at first you don't succeed, skydiving is not for you
 

Reply via email to