[comp.sys.mac.programmer] Mangled Dialog

jmh@ns.network.com (1606) (06/01/89)

The last time I posted this, I wrote the code from memory.
Most of the comments I received were on errors I introduced in trying
to remember the various calls.  The only actual change between the
last crashing dialog handler and this crashing dialog handler is that
the string variable is now a static of size 256.  This does not help:

void handle_my_dialog(theDialog)
DialogPtr theDialog; /* The caller had called GetNewDialog to get this
				pointer */
{
	static char strbuf[256];
	int itt;
	Handle h;
	Rect box;
	int theItem;
	GrafPtr oldport;

	GetPort(&oldport);
	SetPort(theDialog);
	GetDItem(theDialog, 2, &itt, &h, &box);
	sprintf(strbuf+1, "%-3d", val);
	strbuf[0] = strlen(strbuf+1);
	SetIText(h, strbuf);
	do {
		ModalDialog(NIL, &theItem);
		if (theItem == 2 /* yes, this is the right number */)
		{
			GetDItem(theDialog, 2, &itt, &h, &box);
			/* it has been suggested that the above line
			is redundant but harmless */
			GetIText(h, strbuf);
			/* process the text in strbuf */
		}
	} while (theItem != 1 && theItem != 3 && theItem != 4);

	if (theItem == 4) {
		/* reset counters to ignore changes */
	} else {
		/* process changed value */
	}
	SetPort(oldport);
	/* the caller will call CloseDialog *.
}

As I said before, this crash if I invoke it twice.  The second time,
the crash occurs when I try to select the edittext item.  The debugger
frequently prevents the crash.  If it crashes while I am
singlestepping through this routine,  the crash occurs when I call
ModalDialog.

Thanks,
Joel M. Halpern				jmh@nsco.network.com
Network Systems Corporation

tim@hoptoad.uucp (Tim Maroney) (06/02/89)

In article <1424@ns.network.com> jmh@ns.UUCP (Joel Halpern 424-1606) writes:
>The last time I posted this, I wrote the code from memory.
>Most of the comments I received were on errors I introduced in trying
>to remember the various calls.  The only actual change between the
>last crashing dialog handler and this crashing dialog handler is that
>the string variable is now a static of size 256.  This does not help:

Unfortunately, you still haven't posted the actual code.  There is at
least one typo here that would prevent compilation, and in my opinion,
you've probably left out the part that causes the crash.

>void handle_my_dialog(theDialog)
>DialogPtr theDialog; /* The caller had called GetNewDialog to get this
>				pointer */
>{
>	static char strbuf[256];
>	int itt;
>	Handle h;
>	Rect box;
>	int theItem;
>	GrafPtr oldport;
>
>	GetPort(&oldport);
>	SetPort(theDialog);
>	GetDItem(theDialog, 2, &itt, &h, &box);
>	sprintf(strbuf+1, "%-3d", val);
>	strbuf[0] = strlen(strbuf+1);

String constant in code.  Yech.  Non-internationalized number-to-string
conversion.  Double yech.  However, it should work, despite the fact that
you've conjured the variable "val" from nowhere.

The above two lines of code should be "NumToString(val, strbuf);".

>	SetIText(h, strbuf);
>	do {
>		ModalDialog(NIL, &theItem);
>		if (theItem == 2 /* yes, this is the right number */)
>		{
>			GetDItem(theDialog, 2, &itt, &h, &box);
>			/* it has been suggested that the above line
>			is redundant but harmless */

You should definitely leave it in.  Suppose you decide to do another
GetDItem within this loop after removing it; neither you nor Dennis
Ritchie himself is guaranteed to remember that you need to put it back
in at this point.  Removing it makes your code considerably more fragile.

>			GetIText(h, strbuf);
>			/* process the text in strbuf */

I still think this is the step that's most likely to cause a crash;
unfortunately, despite my earlier request, you haven't provided it.

>		}
>	} while (theItem != 1 && theItem != 3 && theItem != 4);
>
>	if (theItem == 4) {
>		/* reset counters to ignore changes */
>	} else {
>		/* process changed value */
>	}

These are also good candidates for crashing.

>	SetPort(oldport);
>	/* the caller will call CloseDialog *.

Non-compilable typographical error.  If you compiled this, the compiler
would treat everything up to the end of the next comment as a comment,
then find itself in an invalid context and complain.  Please post your
complete, original code if you want help!  Nothing you've given here
would cause a crash.

>}
>
>As I said before, this crash if I invoke it twice.  The second time,
>the crash occurs when I try to select the edittext item.  The debugger
>frequently prevents the crash.  If it crashes while I am
>singlestepping through this routine,  the crash occurs when I call
>ModalDialog.

Nasty.  Bugs that don't happen when you use a debugger are known as
demons.  A crash in ModalDialog implies one of two things; either the
front window is not a dialog window (seems unlikely in this case) or
the data structures of the dialog (which may well include the heap data
structures) are screwed up.  Ah, I think I may have it.  You didn't
give the GetNewDialog or CloseDialog calls, but if you call CloseDialog
and you passed NIL for dStorage to GetNewDialog, you could have
corrupted something.  DisposDialog would be appropriate with dStorage
of NIL.  Alternately, if you didn't pass NIL for dStorage, but passed a
buffer smaller than a DialogRecord, that could also have led to
corruption.  In any case, it's pretty clear that the crash is caused by
code which you haven't provided to the net.
-- 
Tim Maroney, Consultant, Eclectic Software, sun!hoptoad!tim
"Prisons are built with stones of Law, Brothels with bricks of Religion."
    - Blake, "The Marriage of Heaven and Hell"

mer@atuan.east.sun.com (Meredith Lesly - Sun ECD TOPS) (06/02/89)

In article <1424@ns.network.com> jmh@ns.UUCP (Joel Halpern 424-1606) writes:
Some code...
>		ModalDialog(NIL, &theItem);

Unless you're still typing it in wrong, you have the arguments to ModalDialog
backwards.

tim@hoptoad.uucp (Tim Maroney) (06/04/89)

In article <594@eagle_snax.UUCP> mer@atuan.east.sun.com (Meredith Lesly -
Sun ECD TOPS) writes:
>>		ModalDialog(NIL, &theItem);
>
>Unless you're still typing it in wrong, you have the arguments to ModalDialog
>backwards.

Not so.  IM says "PROCEDURE ModalDialog(filterProc: ProcPtr; VAR itemHit:
INTEGER);".

By the way, I thought ECD was no longer part of TOPS?
-- 
Tim Maroney, Consultant, Eclectic Software, sun!hoptoad!tim
"What's the ugliest part of your body?
 Some say your nose, some say your toes,
 But I think it's your mind."
-- Frank Zappa