I seem to be getting more than my share of strange errors lately. This
one concerns writing to a global struct from within an MP thread or its
associated event handler. I encountered this error, in a PPx app, as
follows:
I have an MP thread that copies a global struct (one of an STL vector of
structs) to local memory.
tempAns = *Answer;
This works fine.
When the thread finishes, it posts an event to the app queue. This also
works and gets handled properly.
Before posting the event, the thread replaces the global struct with the
local one.
*Answer = tempAns;
This fails -- but not until the app quits. The global struct does,
indeed, get replaced by the local one. ::BlockMoveData (instead of a
direct assignment) gives the error as well.
In debug mode, I get an alert on exit showing
Access fault exception
at which time the stack frame is
start
start
exit
__destroy_global_chain
-->???
This error is perfectly reproducible whenever I write to the global
struct from within the MP code or the event handler. If I write to it
from *outside* this part of the code (e.g., in the top-level app), there
is no error. Moreover, if I define a local struct, ans, in the handler
and write to that, e.g.,
sAnswer ans;
err = ::GetEventParameter(theEvent, 'Answ', kEventParamUserData, nil,
sizeof(sAnswer), nil, &ans);
there is no error. But, if I then copy ans to the global answer, the
error recurs.
It gets even weirder! I tried writing components of the struct
individually and collectively and found that *none* of them (that I
tried) gave an error except one specific long value. I can see nothing
special about this value except that it generates an error when copied
to global memory. Moving this component to a different part of the
struct had no effect. Likewise, renaming it had no effect.
Finally, I have a separate, global struct of the same type (but not in a
vector). If I write to this struct from within the MP code, there is no
error.
Note: struct sAnswer contains no other structures except for
fixed-length arrays.
I find all of this very mysterious and, if anyone has any suggestions,
they would be much appreciated.
TIA.
--
Mike McLaughlin
David Phillip Oster - 27 Nov 2004 21:35 GMT
> In debug mode, I get an alert on exit showing
>
[quoted text clipped - 7 lines]
> __destroy_global_chain
> -->???
This means what it says. When deleting some C++ object, that object
deletes all the objects that it owns. One of those, in turn, was filled
with a byte patter that generates an exception when _it_ tries to delete
the objects that it owns.
Or in your case, a pointer to some object allocated on the thread's
stack is getting copied into your global data structure, so the pointer
is dead after the thread goes away. (Is that member that you think is a
long really a long?)
One common cause of this bug is: not writing copy constructors and
assignment operators when you need them (or writing incorrect ones.)
You now KNOW that what you think you know isn't so. Double check your
data types. Look for classes and structs with pointer members where the
assignment operator and copy constructor should not be blindly copying
the pointer. Look for classes and structs with pointer members where
no-one has written an assignment operator and copy constructor.
Michael McLaughlin - 28 Nov 2004 19:18 GMT
Thank you for the advice. I found the error eventually.
As it turned out, it was not the struct copy (directly) that was the
cause of the problem. [That struct contained no pointers or classes of
any kind.] The real culprit was an inadvertent write beyond the limits
of a local, fixed array.
That will do it everytime :-(
>>In debug mode, I get an alert on exit showing
>>
[quoted text clipped - 26 lines]
> the pointer. Look for classes and structs with pointer members where
> no-one has written an assignment operator and copy constructor.