[comp.sys.mac.programmer] Dialog Crash

jmh@ns.network.com (1606) (05/30/89)

In an application I am attempting to write, I have a dialog with one
edittext item (item 2).  When the dialog is requested from the menu,
the routine starts with:

char strbuf[60];
GetDItem(dialog, 2, handle);
/* set the string at strbuf+1 to the desired display */
trbuf[0] = strlen(strbuf+1);
SetIText(handle, strbuf);

Then I enter a loop:

do {
	ModalDialog(dialog, &theItem);
	if (theItem == 2) {
		GetDItem(dialog, theItem, handle);
		GetIText(handle, strbuf);
		/* process input */
	}
} while (theItem != 1 && tehItem != exititem);

This all works fine the first time I call it.  However,
the second time, the whole system hands.
If I run with LSC breakpoints inside this routine, it runs most of the
time.

I presume I am causing some kind of wandering memory reference.
What?

Any Comments or suggestions would be appreciated.

Joel M. Halpern			jmh@nsco.network.com
Network Systems Corporation	612-424-1606 (office)
				612-824-1375 
				(home evenings central time)


p.s.	obvious errors in the above may be due to not having the
code in front of me, or may be due to my having not understood
what I am supposed to do.  Thanks in all cases.

ksitze@nmsu.edu (Kevin Sitze) (05/31/89)

In article: <jmh@ns.network.com's message of 30 May 89 16:15:45 GMT>
Joel writes:
>In an application I am attempting to write, I have a dialog with one
>edittext item (item 2).  When the dialog is requested from the menu,
>the routine starts with:
>
>char strbuf[60];
>GetDItem(dialog, 2, handle);
>/* set the string at strbuf+1 to the desired display */
>[s]trbuf[0] = strlen(strbuf+1);
>SetIText(handle, strbuf);
>
>Then I enter a loop:
>
>do {
>	ModalDialog(dialog, &theItem);
>	if (theItem == 2) {
>		GetDItem(dialog, theItem, handle);
>		GetIText(handle, strbuf);
>		/* process input */
>	}
>} while (theItem != 1 && tehItem != exititem);

Your problem lies in an incorrect call to GetDItem as well as a bad
call to ModalDialog.  You're code should look like this: (Plus some
streamlining...) (Changed lines are marked with a '>')

>#define NIL (0L)
char strbuf[60];
>GetDItem(dialog, 2, &itmKind, &myHandle, &myRect);
/* set the string at strbuf+1 to the desired display */
strbuf[0] = strlen(strbuf+1);
SetIText(myHandle, strbuf);
do {
>	ModalDialog(NIL, &theItem);	/*
	if (theItem == 2) {
>		/* the call to GetDItem is not needed here, already	*/
>		/* have info that was needed, namely myHandle.		*/
>		GetIText(myHandle, strbuf);
		/* process input */
	}
} while (theItem != 1 && theItem != exitite);

I changed your 'handle' variable to 'myHandle' because I program in
LSP (which is not case-sensitive) and I don't like seeing
'duplications' between types and variables. (No particular reason...)

ModalDialog assumes that the first parameter being passed is a pointer
to a filter _function_, NOT a dialog (as you seemed to have done here).

This will most probably cause an address error (Error #02 in the
SysError dialog box) when you do anything at all with that dialog.

I'm surprised that LSC allowed you to compile the above code because
ususally it does type-checking on ROM calls (they ARE after all,
PASCAL calls)  Rich, any ideas?

				-Kelesi
--
+--------------------------------------------------------------------+
| From the Macintosh of: Kevin L. Sitze. This is ME: ksitze@NMSU.edu |
+------------------------------------------------------+-------------+
| The difference between intelligence and stupidity is |   Is this   |
| that intelligence has a limit.          -- anonymous |   better?   |
+------------------------------------------------------+-------------+

tim@hoptoad.uucp (Tim Maroney) (05/31/89)

In article <1415@ns.network.com> jmh@ns.UUCP (Joel Halpern 424-1606) writes:
>In an application I am attempting to write, I have a dialog with one
>edittext item (item 2).  When the dialog is requested from the menu,
>the routine starts with:
>
>char strbuf[60];
>GetDItem(dialog, 2, handle);

Incorrect call to GetDItem.  Both MPW and LSC would flag this as having
too few parameters.  Check the calling sequence in Inside Mac.  Even
after you correct this to include "itemType" and "box", you will have
to watch your VAR parameters; that "handle" needs to be "&handle".  LSC
would *not* flag this error, since it only checks argument sizes to
toolbox traps, and a pointer to a handle is the same size as a handle.

>/* set the string at strbuf+1 to the desired display */
>trbuf[0] = strlen(strbuf+1);
>SetIText(handle, strbuf);

Could work, assuming there's a C string of no more than 58 characters
at strbuf + 1.  But how'd that get there?  If you called GetIndString,
you need to provide a 256-character buffer.  If you put it as a string
constant, shame on you....

>Then I enter a loop:
>
>do {
>	ModalDialog(dialog, &theItem);

Incorrect call to ModalDialog.  I can't believe this would run even
once without crashing, because you are passing your dialog pointer as
the address of a filter routine.  The PC will be JSR'd to the dialog
pointer, and havoc will ensue.  Is this the actual code?  If not,
there's no way the net will be able to find your problem.

>	if (theItem == 2) {
>		GetDItem(dialog, theItem, handle);
>		GetIText(handle, strbuf);
>		/* process input */

For all we know, the crash might be in "process input"....

>	}
>} while (theItem != 1 && tehItem != exititem);

Clearly not the actual code; your references to "tehItem" and "trbuf"
make that clear.  However, I would beware of passing any string of less
than 256 characters to a routine like GetIText or GetIndString that
takes a Str255.  It's definitely not safe with GetIText, since the user
can crash your program just by entering more than 59 characters in this
case; many implementations of GetIndString also assume they can use a
256-character buffer.  Also, you've called GetDItem wrong again.

>This all works fine the first time I call it.  However,
>the second time, the whole system hands.

This code wouldn't even compile, much less run.  Please use cut and
paste in your terminal emulator to post the actual code.  However, my
guess would be that you need to be using "&handle" in the GetDItem
calls and all the other problems are artifacts in retyping the code,
not present in the orginal.  The GetDItem calls wouldn't compile as you
have them, and the ModalDialog call would crash every time, practically
guaranteed by God.
-- 
Tim Maroney, Consultant, Eclectic Software, sun!hoptoad!tim
"Disclaimers are for running-dog lackeys of the bourgeoisie; free-thinking
members of the proletariat such as myself have their own opinions, and do
not need to express those of their oppressive capitalistic employers!
Nyah!" -- James Heath

siegel@endor.harvard.edu (Rich Siegel) (05/31/89)

In article <KSITZE.89May30122016@picuris.nmsu.edu> ksitze@nmsu.edu (Kevin Sitze) writes:
>
>I'm surprised that LSC allowed you to compile the above code because
>ususally it does type-checking on ROM calls (they ARE after all,
>PASCAL calls)  Rich, any ideas?

	LightspeedC doesn't type-check anything, unless it's prototyped. In
the case of pascal-style functions that aren't prototyped, the number and
size of parameters is checked, but not the type.

		--Rich



~~~~~~~~~~~~~~~
 Rich Siegel
 Staff Software Developer
 Symantec Corporation, Language Products Group
 Internet: siegel@endor.harvard.edu
 UUCP: ..harvard!endor!siegel

 "She told me to make myself comfortable, so I pulled down my pants
 and sat in the pudding." -Emo Phillips
~~~~~~~~~~~~~~~