[comp.sys.mac.programmer] Help! 'Monitors' cdev related bug.

larryh@tekgvs.TEK.COM (Larry Hutchinson) (03/08/88)

Is anyone aware of problems with the 'Monitors' cdev in the current
system release?

I have a very nasty bug in an application I am working on (or in the
'Monitors' cdev).  The bug is very difficult to reproduce.  
It manifests itself as a bus error when changing the number
of colors using the control panel.  I am 80% sure the problem is with
my code but would like to check with you folks first.

Additional info for those who like this sort of thing:

The bus error occurs deep within the cdev -- after it has done an
InitGDevice and appears to be walking the window list. I suspect that
it bombs when it hits one of my windows that uses an offscreen bitmap.
This window destroys and recreates the offscreen bitmap whenever the
number of bits per pixel changes.  Thus a lot of heap activity takes place
when the # of colors is changed in the control panel.  One thing in
this mess of code that I am unsure about is the fact that I steal the
pixMapHandle from a freshly created color graf port and keep it around
for when the screen needs updating.  Since the graf port is transient,
I install a sacrificial fake pixMapHandle (via NewHandle(0L)) before
disposing of the color graf port.  Is this ok?  Should I clone the
pixMapHandle rather than using a fake one for disposal?  Otherwise,
I am pretty much using the technique described in TN120 (or whatever
-- this is from memory).

The problem does NOT appear to occur more frequently under TMON's heap
scramble and check.

Discipline reveals a questionable _RecoverHandle in the cdev code that
is using an address below the application heap.  Perhaps this is just the
system heap and TMON does not recognize it.  (It occurs continuously while
the control panel is running ( and not just the Monitors cdev).  This is
the only thing revealed by Discipline.

There is plenty of memory available.

There are around 300 objects in the heap.  The heap "looks" ok.

Multifinder is not running.

The bus error occurs BEFORE my windows are updated.  Perhaps something
becomes foobar from a previous change -- I have to change the '# of colors'
several times before the bomb occurs.

I have finally found a sequence of events that will always produce
the problem and will be spending time single stepping thru the cdev
unless I get an indication from you folks that it may not be my
problem.

Thanks for any info,



Larry Hutchinson, Tektronix, Inc. PO Box 500, MS 50-383, Beaverton, OR 97077
UUCP:   [uunet|ucbvax|decvax|ihnp4|hplabs]!tektronix!tekgvs!larryh
ARPA:   larryh%tekgvs.TEK.COM@RELAY.CS.NET
CSNet:  larryh@tekgvs.TEK.COM

larryh@tekgvs.TEK.COM (Larry Hutchinson) (03/09/88)

In article <3189@tekgvs.TEK.COM> larryh@tekgvs.TEK.COM (Larry Hutchinson) writes:
>
>Is anyone aware of problems with the 'Monitors' cdev in the current
>system release?
>
>I have a very nasty bug in an application I am working on (or in the
>'Monitors' cdev).  The bug is very difficult to reproduce.  
>It manifests itself as a bus error when changing the number
>of colors using the control panel.  I am 80% sure the problem is with
>my code but would like to check with you folks first.

Well, I couldn't wait for responses and did some more single stepping thru the
cdev code and found the bug.  It was indeed my fault but I think you will find
the result interresting and instructive.

It turns out that the problem was lurking in my code for almost a year.
I had embedded a GrafPort in a relocateable structure.  Now, don't
everyone go 'Ooooh' at once! -- I always locked the structure when the
port was in use.  In traceing thru the cdev code, I discovered that it
sequences thru an array of GrafPtrs and does an InitPalette or some such
on any CGrafPorts that it finds.  I was unaware that this list of GrafPorts
existed.  (You can find it via a Handle to the list stored at 0xD66 (PortList)
the first word is the count of GrafPtrs in the list)  The address
placed in this list was where the port was when I did an OpenPort on it but
since it was allowed to move between uses, the address became invalid.

Another way one could run into this problem is if one forgets to do a
ClosePort when finished with a port.  IM warns that the memory allocated
to a few handles will be lost but this cdev stuff is more serious.

Let that be a lesson to me!


Larry Hutchinson, Tektronix, Inc. PO Box 500, MS 50-383, Beaverton, OR 97077
UUCP:   [uunet|ucbvax|decvax|ihnp4|hplabs]!tektronix!tekgvs!larryh
ARPA:   larryh%tekgvs.TEK.COM@RELAY.CS.NET
CSNet:  larryh@tekgvs.TEK.COM

dgold@Apple.COM (David Goldsmith) (03/09/88)

In article <3189@tekgvs.TEK.COM> larryh@tekgvs.TEK.COM (Larry Hutchinson) writes:
>
>Is anyone aware of problems with the 'Monitors' cdev in the current
>system release?
>
>I have a very nasty bug in an application I am working on (or in the
>'Monitors' cdev).  The bug is very difficult to reproduce.  
>It manifests itself as a bus error when changing the number
>of colors using the control panel.  I am 80% sure the problem is with
>my code but would like to check with you folks first.
>...
>I have finally found a sequence of events that will always produce
>the problem and will be spending time single stepping thru the cdev
>unless I get an indication from you folks that it may not be my
>problem.

It's almost certainly your problem.  Color Quickdraw keeps a data structure
called the port list which is a list of all the open grafports in the system.
When you change the bit depth via Monitors, it walks the port list and updates
the PixMap data structures that they refer to (assuming they refer to the
screen) to reflect the new bit depth.

Ways in which a crash can occur are if you improperly maintain your GrafPorts
or if a GrafPort contains garbage (such as an invalid PixMap handle).  One
common error is to keep a GrafPort in a handle.  This doesn't work.  If
a GrafPort moves between OpenPort and ClosePort, the port list is pointing
at garbage.  Another is to dispose of a port via DisposPtr without doing a
ClosePort first.  Again, the port list is corrupted.  GrafPorts are non-
relocatable objects which must be properly maintained.

From what you say, I suspect your problem arises from the empty handle which
you have stuffed in the grafport.  The handle must be a valid PixMap data
structure.  In general, messing around with data structures behind the
ROM's back is a good way to run into trouble in the present or the future.
There are routines for setting and retrieving the port's pixmap, and for
creating new pixmaps from scratch; these are better to use then mucking
with stuff directly.