[This is the second of two posts on the same thread, describing
the solution to the problem and raising a few further questions]
>Well, I've gotten extremely deep into the bug this thread
>started with (occurrence of the error message "Form.c, Line:649,
>Windows cannot be under forms because they can't be redrawn"
>under a debug OS 3.5 ROM). But not deep enough -- I still
>haven't solved it.
>
>As stated in the original posting, this CodeWarrior application
>is large, a nearly 200k database. It contains multiple segments,
>and uses the "smart" code model. It is in C++.
>
>While keeping nearly all the code in the application intact, I
>have been able to reduce the actual execution path so that it
>just calls FrmAlert immediately after being launched. Upon
>dismissing the alert, I get the above-cited error message.
>
>In the app's starter module (containing PilotMain()), I can trim
>out some code (none of which is being executed in this
>drastically shortened execution path) and reach a version where
>the error message no longer occurs. The cutting can be done
>several ways; I've tried to find patterns, but so far haven't
>succeeded. I thought for a while that it was a simple matter of
>the code size exceeding some threshold, but have disproved
>that. I've tried going Large Model, and splitting up segments;
>neither affects the behavior. Upon reaching a version of the
>module that didn't cause the error, I tried putting a bunch of
>lines of irrelevant (non-executed) code back in just to swell
>the size, but didn't succeed in making the error happen again.
>
>Whereas adding back certain other, less voluminous but still
>unexecuted, lines of code *did* bring the error back.
The problem turned out to be code in a C++ static initializer
that was creating a window before PilotMain() was called. The
first time any dialog was dismissed, the checks in FrmEraseForm()
complained about the fact that there was no way of restoring the
contents of that window, with the above-cited message.
Part of my difficulty was that I didn't expect the CodeWarrior
linker to be as ruthless as it actually is. When one explicitly
specifies that a code module is to be included in a target, I
expect the linker to put it in the executable, whether or not
anything else actually depends on it. But CW evidently does not
do so, instead determining the contents of the executable as the
transitive closure of a dependency tree rooted in the main
function, in the way that traditional linkers handle
libraries. Even more surprising is the evident fact that the CW
linker is not even limited to just including or excluding a whole
code module -- it will include some *functions* out of a code
module and leave out others, if there are no references to them.
I would have gotten to the root of my problem a lot faster if I
had just looked at the sizes of the .prc files -- the ones in
which my original problem occurred were about 13 times the size
of those in which it did not occur! By turning off one last line
of code in the main module, I unknowingly removed a critical
dependency, causing the linker to omit 90-odd percent of the rest
of the modules, including the one with the offending static
initializer.
Strictly speaking, it is not correct for a C++ linker to use this
sort of heuristic: the programmer should be able to specify that
a particular module is to be included, exactly *because* he needs
the side-effects of a static initializer in that module.
As far as I can see, none of the linker's behavior is mentioned
in CodeWarrior documentation.
Speaking of static initializers, I'm curious whether they're
*ever* acceptable in PalmOS applications: will they be executed
even when the application is launched with a launch code for
which global variables aren't available? If so, the static
initialization code is pretty much guaranteed to be accessing
non-existent memory (or some other application's memory?). Does
anyone know the answer to this question?
--Greg Lutz
NearSpace, Inc.
--
For information on using the Palm Developer Forums, or to unsubscribe, please see
http://www.palm.com/devzone/mailinglists.html