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:
- Mimic the PalmOS global space allocation. This would ideally be done by the DA launcher, but can be done by the DA itself.
- 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.
- 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.
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.
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]>
- http://member.nifty.ne.jp/yamakado/da/ - The DA L10 4En Project
Sergio Carvalho
---------------
[EMAIL PROTECTED]
If at first you don't succeed, skydiving is not for you
