[comp.sys.amiga.programmer] What the #&%@?

lkoop@pnet01.cts.com (Lamonte Koop) (03/06/91)

I have come face to face with a rather perplexing problem involving a project
I am currently working on, to which I cannot find the answer.  I'm hoping
SOMEONE [read: ANYONE! please!] may have an idea as to what is going on. 
Anyway, the problem goes like this:  The application I have set up uses a
fairly standard Intuition interface setup...with the appropriate message
handling loops and such.  The problem arises when the code I compile is
executed on a stock 68000-based system (I am currently developing on a
68030-accelerated system).  The event handling loops run perfectly normal when
run on the 68030 (or a 68020 for that matter)...unfortunately, things begin to
flake out when the program is run in the machine's 68000 mode...or any
68000-based system.  The symptoms are thus:  at VERY random times, selecting a
menu item will result in an Address error guru.  Now, most of the menu
selections simply result in a function call or so.  The odd part is that there
is NO way to predict which menu function will guru...or WHEN...It just
happens.  This does not happen AT ALL when the program is run under an 020 or
030 system. [No...the compiler is NOT set to compile for 020/030 specific code
generation].  The layout of the event loop skeleton is somewhat like this:

while(keepgoing) {
   Wait(1L << BenchWindow->UserPort->mp_SigBit);
   while((msg = (struct IntuiMessage *)GetMsg(BenchWindow->UserPort))) {
     code = msg->Code;  class = msg->Class;
     gad = ((struct Gadget *)msg->IAddress)->GadgetID;
     ReplyMsg((struct Message *)msg);

     switch(class) {  /*start of the action-determining section*/
        case MENUPICK : 
             mnum = MENUNUM(code);
             mitem = ITEMNUM(code);
             subitem = SUBNUM(code);
             switch(mnum) {  /*Determine action according to which menu*/
                case 0 :
                     if(!ShowAbout()) Error("Insufficient Memory!");
                     break;
                case 1 :
                     if(!DoSysInfo()) Error("Unable to open window!");
                     break;
 
Well, anyway that's the general idea.  There's more for processing gadgets,
(and the rest of the menu items).  For example...case 1 above for menu 0 [the 
DoSysInfo() call] will guru...SOMETIMES on a 68000 machine...NEVER on an 020
or 030 machine.  The same goes for various other items.  Generally, the GURUs
start to appear after I've done some other action first...but I've had them
happen right off.  I've been trying to figure this out for a week now with no
ideas at all.
 
Additional info:  I'm using Lattice C 5.10a, with the following compile
options:   -ma  (any processor code...will run on any machine, optimized to
                 68010 timing when it won't degrade 68000 performance...does
                 not generate 010+ specific code..will run on an '000)
           -mt  (optimize time)
           -b1  (base A4 data addressing)
           -r1  (PC-relative 16-bit offset function calls)
           -v   (stack checking off (NO..this is not the problem...this I 
                 have determined))
           -O   (optimize)
Link options are:
           SMALLCODE
           SMALLDATA
           DEFINE @_main=@_tinymain
[Yes....I am using register parameters for all function calls (-rr option for
compile)]

I do note that when I link...I get a blink message three times:
Error 515: An ALV was generated pointing to function @XCEXIT
NOALVS as an option to blink does nothing to this...but even given this, 
it still would not explain this bizarre behavior.  ANY IDEAS folks?
Feel free to E-Mail me, or post here, as I read the group regularly.
I aplogize sincerly for taking up so much bandwidth, but this is driving me
crazy...


                             LaMonte Koop
 Internet: lkoop@pnet01.cts.com         ARPA: crash!pnet01!lkoop@nosc.mil
           UUCP: {hplabs!hp-sdd ucsd nosc}!crash!pnet01!lkoop
 "It's a dog-eat-dog world...and I'm wearing Milk Bone underwear"--Norm

lkoop@pnet01.cts.com (Lamonte Koop) (03/06/91)

lkoop@pnet01.cts.com (Lamonte Koop) writes:
>
>I have come face to face with a rather perplexing problem involving a project
>I am currently working on, to which I cannot find the answer.  I'm hoping


Well, I found it...

>SOMEONE [read: ANYONE! please!] may have an idea as to what is going on. 
>Anyway, the problem goes like this:  The application I have set up uses a
>fairly standard Intuition interface setup...with the appropriate message
>handling loops and such.  The problem arises when the code I compile is
>executed on a stock 68000-based system (I am currently developing on a
>68030-accelerated system).  The event handling loops run perfectly normal when
>run on the 68030 (or a 68020 for that matter)...unfortunately, things begin to
>flake out when the program is run in the machine's 68000 mode...or any
>68000-based system.  The symptoms are thus:  at VERY random times, selecting a
>menu item will result in an Address error guru.  Now, most of the menu
                             ^^^^^^^^^^^^^
          tip off right here-------|

>selections simply result in a function call or so.  The odd part is that there
>is NO way to predict which menu function will guru...or WHEN...It just
>happens.  This does not happen AT ALL when the program is run under an 020 or
>030 system. [No...the compiler is NOT set to compile for 020/030 specific code
>generation].  The layout of the event loop skeleton is somewhat like this:
>
>while(keepgoing) {
>   Wait(1L << BenchWindow->UserPort->mp_SigBit);
>   while((msg = (struct IntuiMessage *)GetMsg(BenchWindow->UserPort))) {
>     code = msg->Code;  class = msg->Class;
>     gad = ((struct Gadget *)msg->IAddress)->GadgetID;

Ok, the above line is the problem.  I thought I would post this just as a
follow-up and warning for anyone who might accidentally do something this
dumb.  Ok, the assignment to the variable 'gad' above is compiled to the
following machine code:

       206B 001C         MOVEA.L   001C(A3),A0
       3B68 0026 FFEA    MOVE.W    0026(A0),FFEA(A5)

Now, the reason this SOMETIMES crashes, and only on a 68000/68010 came to me
after a rather lengthy fit about the whole mess.  The 'gad' assignment is made
regardless of whether or not the IntuiMessage is a 'gadget' type of message.
I just assumed (wrongly) that if it wasn't a gadget message, then it wouldn't
matter what was assigned to gad...but I wasn't thinking of HOW it was
assigned.  Every now and then, it's possible that dereferencing the
msg->IAddress pointer the way I was would result in an ODD address.  Now, the
68020, 030, etc don't require DATA to be word aligned, (they just incur a
performance hit for accessing such misaligned data)...so such references in
the context given above (the disassembled code) had no ill effects on my
system when I was in my normal state (running on the 030).  However, the 68000
DOES require word alignment of such data accesses, and thus on the occasions
when A0 ended up ODD from my bizarre reference to msg->IAddress, an Address
Error guru would occur. (i.e: BOOM).  Note that this condition would only
occur when the message was not a gadget message...and in such cases the
occurance was still fairly "random" in nature (it would'nt ALWAYS end up odd)
 
The moral of the story:  Don't make stupid assumptions :-).


                             LaMonte Koop
 Internet: lkoop@pnet01.cts.com         ARPA: crash!pnet01!lkoop@nosc.mil
           UUCP: {hplabs!hp-sdd ucsd nosc}!crash!pnet01!lkoop
 "It's a dog-eat-dog world...and I'm wearing Milk Bone underwear"--Norm

jlavin@cie.uoregon.edu (Jeff Lavin) (03/06/91)

In article <7823@crash.cts.com> lkoop@pnet01.cts.com (Lamonte Koop) writes:
>
>I have come face to face with a rather perplexing problem involving a project
>I am currently working on, to which I cannot find the answer.  I'm hoping
>SOMEONE [read: ANYONE! please!] may have an idea as to what is going on. 
>Anyway, the problem goes like this:  The application I have set up uses a
>fairly standard Intuition interface setup...with the appropriate message
>handling loops and such.  The problem arises when the code I compile is
>executed on a stock 68000-based system (I am currently developing on a
>68030-accelerated system).  The event handling loops run perfectly normal when
>run on the 68030 (or a 68020 for that matter)...unfortunately, things begin to
>flake out when the program is run in the machine's 68000 mode...or any
>68000-based system.  The symptoms are thus:  at VERY random times, selecting a
>menu item will result in an Address error guru.  Now, most of the menu
>selections simply result in a function call or so.  The odd part is that there
>is NO way to predict which menu function will guru...or WHEN...It just
>happens.  This does not happen AT ALL when the program is run under an 020 or
>030 system. [No...the compiler is NOT set to compile for 020/030 specific code
>generation].  The layout of the event loop skeleton is somewhat like this:
>
>while(keepgoing) {
>   Wait(1L << BenchWindow->UserPort->mp_SigBit);
>   while((msg = (struct IntuiMessage *)GetMsg(BenchWindow->UserPort))) {
>     code = msg->Code;  class = msg->Class;
>     gad = ((struct Gadget *)msg->IAddress)->GadgetID;
                                     ^^^^ Right thar!
>     ReplyMsg((struct Message *)msg);
>
>     switch(class) {  /*start of the action-determining section*/
>        case MENUPICK : 
>             mnum = MENUNUM(code);
>             mitem = ITEMNUM(code);
>             subitem = SUBNUM(code);
>             switch(mnum) {  /*Determine action according to which menu*/
>                case 0 :
>                     if(!ShowAbout()) Error("Insufficient Memory!");
>                     break;
>                case 1 :
>                     if(!DoSysInfo()) Error("Unable to open window!");
>                     break;
> 
>Well, anyway that's the general idea.  There's more for processing gadgets,
>(and the rest of the menu items).  For example...case 1 above for menu 0 [the 
>DoSysInfo() call] will guru...SOMETIMES on a 68000 machine...NEVER on an 020
>or 030 machine.  The same goes for various other items.  Generally, the GURUs
>start to appear after I've done some other action first...but I've had them
>happen right off.  I've been trying to figure this out for a week now with no
>ideas at all.
> 
> [stuff deleted]

Your problem has to do with the fact that an '020 or '030 allows access to
words or longwords on odd boundaries.  When you have a 68000 this will cause
an address bus error.

When an IntuiMsg of CLASS(MENUPICK) comes in, im_IAddress is undefined.
As such, it will occasionally happen to be an odd address.  You are having
this problem because you are performing an operation in this field *before*
finding out if it was a GADGETUP or GADGETDOWN class.

The fix is easy: Just store the value in im_IAddress.  Don't extract the
gg_GadgetID or anything else until you know what, if anything, im_IAddress
is pointing to.


The Puzzle Factory, Inc.  | Jeff Lavin -- jlavin@cie.uoregon.edu
Veneta, Oregon            |-------------------------------------
Voice : (503) 935-3709    | Remainder of signature line
Data  : (503) 935-7883    | under construction.

davidj@cbmvax.commodore.com (David N. Junod) (03/06/91)

In article <7823@crash.cts.com> lkoop@pnet01.cts.com (Lamonte Koop) writes:
>
>I have come face to face with a rather perplexing problem involving a project
>I am currently working on, to which I cannot find the answer.  I'm hoping
>
>while(keepgoing) {
>   Wait(1L << BenchWindow->UserPort->mp_SigBit);
>   while((msg = (struct IntuiMessage *)GetMsg(BenchWindow->UserPort))) {
>     code = msg->Code;  class = msg->Class;
>     gad = ((struct Gadget *)msg->IAddress)->GadgetID;

You can not assume that IntuiMessage->IAddress is always a gadget!  You're
referencing 'random' memory.  Only pull the GadgetID on GADGETDOWN and
GADGETUP events.

>                             LaMonte Koop
> Internet: lkoop@pnet01.cts.com         ARPA: crash!pnet01!lkoop@nosc.mil
>           UUCP: {hplabs!hp-sdd ucsd nosc}!crash!pnet01!lkoop
> "It's a dog-eat-dog world...and I'm wearing Milk Bone underwear"--Norm

~DNJ~