Amiga.org

Operating System Specific Discussions => Amiga OS => Amiga OS -- Development => Topic started by: Jose on February 26, 2007, 08:07:56 PM

Title: SOLVED_GfxLibrary madness.. stack overflow WTF ?!!
Post by: Jose on February 26, 2007, 08:07:56 PM
This small code snippet I made crashes, and when inspecting with SASC debugger I get a stack overflow. It even manages to crash Microsoft's VC library that WinUAE uses:)
The weird thing is that it crashes upon entering a function that doesn't even use the stack :) (DestroyScrn()).

Code: [Select]
#include <exec/types.h>
#include <graphics/gfx.h>
#include <graphics/gfxbase.h>
#include <graphics/view.h>
#include <graphics/displayinfo.h>
#include <graphics/gfxmacros.h>
#include <graphics/videocontrol.h>
#include <libraries/dos.h>

#include <utility/tagitem.h>
#include <stdio.h>
#include <stdlib.h>


#include <clib/graphics_protos.h>
#include <clib/exec_protos.h>
#include <clib/dos_protos.h>

LONG OpenStuff(void);
void CloseStuff(void);
LONG MkScrn(void);
void DestroyScrn(void);
void ProcErr(WORD ErrCd);
void DestroyScrn(void);

/* Disable Ctrl+C handling */
/* VOID _chkabort (VOID); */


struct GfxBase *GfxBase = NULL;

struct View Vw, *oldVw = NULL;
struct ViewExtra *VwXtr = NULL;
struct ViewPort Vp;
struct ViewPortExtra *VpXtr = NULL;
struct ColorMap *Cm = NULL;
struct RasInfo Ri;
struct BitMap Bm;
struct MonitorSpec *monspec = NULL;

/* Color table for base colors */
struct ClrTbl
{ UWORD NrClrs;
  UWORD FrstClr;
  struct ClrEntry
  { ULONG Red;
    ULONG Green;
    ULONG Blue;
  } Clrs[64];
} ClrTbl;


int main (int argc, char **argv)
{ LONG RtVl;

  if (RtVl = OpenStuff())
    ProcErr(RtVl);
 
  /* Preserve old view 2 restore it on exit */
  oldVw = GfxBase->ActiView;
 
  if (RtVl = MkScrn ())
    ProcErr(RtVl);
  else
    { Delay (6 * TICKS_PER_SECOND);
    }
 
  END:
  LoadView(oldVw);
  WaitTOF();
  DestroyScrn();
  CloseStuff();
  exit(0);
}


LONG OpenStuff()
{ LONG RetVl = 0;

  if (!(GfxBase = (struct GfxBase *)OpenLibrary(&quot;graphics.library&quot;, 39L)))
    RetVl = 50;
 
  return (RetVl);
}


void CloseStuff (void)
{ if (GfxBase)
    CloseLibrary ((struct Library *)GfxBase);
}


LONG MkScrn ()
{ WORD Err = 0;
  WORD Cntr;
  struct TagItem vcTags[] =
  { VTAG_ATTACH_CM_SET, NULL,
    VTAG_VIEWPORTEXTRA_SET, NULL,
    VTAG_NORMAL_DISP_SET, NULL,
    VTAG_END_CM, NULL
  };
  ULONG modeID = HIRESHAMLACE_KEY;
  struct DimensionInfo dimquery;

  InitView (&Vw);
  if (!(VwXtr = GfxNew(VIEW_EXTRA_TYPE)))
    Err = 1;
  else
    { GfxAssociate(&Vw, VwXtr);
      Vw.Modes |= EXTEND_VSTRUCT;
     
      if (!(VwXtr->Monitor = OpenMonitor(NULL, modeID)))
        Err = 2;
     
      InitBitMap(&Bm, 8, 640, 480);
      for (Cntr = 0; Cntr < 8; Cntr++)
        Bm.Planes[Cntr] = NULL;
      for (Cntr = 0; Cntr < 8; Cntr++)
        if (!(Bm.Planes[Cntr] = (PLANEPTR)AllocRaster(640, 480)))
          { Err = 3;
            break;
          }

      if (!Err)
        { Ri.BitMap = &Bm;
          Ri.RxOffset = 0;
          Ri.RyOffset = 0;
          Ri.Next = NULL;
         
          InitVPort(&Vp);
          Vw.ViewPort = &Vp;
          Vp.RasInfo = &Ri;
          Vp.DHeight = 480;
   Vp.DWidth = 640;
   Vp.DyOffset = 0;
   Vp.DxOffset = 0;
         
          if (!(VpXtr = GfxNew(VIEWPORT_EXTRA_TYPE)))
            Err = 4;
          else
            { vcTags[1].ti_Data = (ULONG)VpXtr;
              if (!(GetDisplayInfoData(NULL, (UBYTE *) &dimquery, sizeof (dimquery), DTAG_DIMS, modeID)))
                Err = 5;
              else
                { VpXtr->DisplayClip = dimquery.Nominal;
                 
                  if (!(vcTags[2].ti_Data = (ULONG) FindDisplayInfo(modeID)))
                    Err = 6;
                  else
                    { ClrTbl.NrClrs = 64;
                      ClrTbl.FrstClr = 0;

                      for (Cntr = 64; Cntr; Cntr--)
                        { ClrTbl.Clrs[Cntr].Red = 0xffffffff;
                          ClrTbl.Clrs[Cntr].Green = 0L;
                          ClrTbl.Clrs[Cntr].Blue = 0L;
                        }
                     
                      vcTags[0].ti_Data = (ULONG)&Vp;
                     
                      if (!(Cm = GetColorMap (64L)))
                        Err = 7;
                      else if (VideoControl (Cm, vcTags))
                        Err = 8;
                      else
                        { LoadRGB32 (&Vp, (ULONG *)&ClrTbl);
                          MakeVPort (&Vw, &Vp);
                          MrgCop (&Vw);
                         
                          /* Clear screen */
                          for (Cntr = 0; Cntr < 8; Cntr++)
                            BltClear((UBYTE *)Bm.Planes[Cntr], Bm.BytesPerRow * Bm.Rows, 1L);
                         
                          /*LoadView(&Vw);*/
                        }
                    }
                }
            }
        }
    }

  return (Err);
}


void ProcErr(WORD ErrCd)
{ printf (&quot;Err %d\n&quot;, ErrCd);
 
  DestroyScrn();
}


void DestroyScrn ()
{ WORD Cntr;

  if (Vw.LOFCprList)
    FreeCprList (Vw.LOFCprList);
  if (Vw.SHFCprList)
    FreeCprList(Vw.SHFCprList);
 
  FreeVPortCopLists(&Vp);
 
  if (Cm)
    FreeColorMap(Cm);
  if (VpXtr)
    GfxFree (VpXtr);
  for (Cntr = 0; Cntr < 8; Cntr++)
    if (Bm.Planes[Cntr])
      FreeRaster (Bm.Planes[Cntr], 640, 480);
 
  if (VwXtr)
    { if (VwXtr->Monitor)
    CloseMonitor (VwXtr->Monitor);
      GfxFree (VwXtr);
    }
}


Any ideas ? :idea:
Title: Re: GfxLibrary madness.. stack overflow WTF ?!!
Post by: Jose on February 26, 2007, 08:10:48 PM
BTW, it crashes upon entering DestroyScrn().
I've also commented LoadView to allow me to continue to see the workbench when using the debugger...

Title: Re: GfxLibrary madness.. stack overflow WTF ?!!
Post by: Homer on February 26, 2007, 08:33:06 PM
Nope, you lost me just after "This"  :lol:
Title: Re: GfxLibrary madness.. stack overflow WTF ?!!
Post by: motorollin on February 26, 2007, 08:55:55 PM
Increase the stack? :-P

--
moto
Title: Re: GfxLibrary madness.. stack overflow WTF ?!!
Post by: ChaosLord on February 26, 2007, 09:06:49 PM
1. All functions use the stack.  That is where the return address is pushed to / pulled from.

2. If anything corrupts memory then the debugger can go totally insane and report insane falsely untrue factual things which definitely may or may not be right.

Just letting you know  :-)
Title: Re: GfxLibrary madness.. stack overflow WTF ?!!
Post by: Jose on February 26, 2007, 09:11:43 PM
@moto

Done it already :) Same result even with up to 1MB stack....
Title: Re: GfxLibrary madness.. stack overflow WTF ?!!
Post by: mel_zoom on February 26, 2007, 09:18:55 PM
I cant say what is wrong here but surely it cant be what it claims to be. I remember reading that amiga functions use very little stack.

From my understanding of C so far all of the local variables that arent "static" are put on the stack and also the stack is used to store where the program is up to when you call a function.

Maybe something is overwriting something it shouldnt and you are getting misleading errors?
Title: Re: GfxLibrary madness.. stack overflow WTF ?!!
Post by: Jose on February 26, 2007, 09:20:16 PM
@ChaosLord
Yeah, 2 is very likely. I read the Gfx library on the RKM's a few times and today I finally rushed to mess with it Ironically there was a forum post today by the Friedens that it will be completely replaced on OS4... lost hours I spend reading about it, I know the function of almost every display structure by now :cry:
Title: Re: GfxLibrary madness.. stack overflow WTF ?!!
Post by: Jose on February 26, 2007, 09:37:25 PM
"...Maybe something is overwriting something it shouldnt and you are getting misleading errors?"

Yeah... don't have any patience left to look more into it right now.
Will come back later, meanwhile if anyone is brave enouph to try..
Title: Re: GfxLibrary madness.. stack overflow WTF ?!!
Post by: Doobrey on February 26, 2007, 10:08:25 PM
@Jose
 Probably a silly question, but do you run any other tools such as Enforcer(or WinUAEenforcer),Mungwall, Memsniff or Wipeout to see if your program is acting up anywhere before it crashes ?
Title: Re: GfxLibrary madness.. stack overflow WTF ?!!
Post by: Jose on February 26, 2007, 11:30:51 PM
@Doobrey
It's on my to do list for a long time but after I switched to SASC because of the cool debugger it has didn't felt much need.

BTW I found the bug (silly one it is)

It's one this block of code:
Code: [Select]
for (Cntr = 64; Cntr; Cntr--)
{ ClrTbl.Clrs[Cntr].Red = 0xffffffff;
  ClrTbl.Clrs[Cntr].Green = 0L;
  ClrTbl.Clrs[Cntr].Blue = 0L;
}


The array is a 64 element one so this starts off boundary...
And it works! Steals the screen from all applications and makes it red screen for 6 seconds :-D
First gfx code I've ever made, there's something magical about seeing your code display and manipulate the screen, even for a stupid one like this :lol:
One cool thing that I like about it is that I made it using the lowest gfx calls that exist.
I'm also glad that I found the bug before someone else.. :-)
Title: Re: SOLVED_GfxLibrary madness.. stack overflow WTF ?!!
Post by: itix on February 27, 2007, 01:29:38 AM
Quote

int main (int argc, char **argv)
{ LONG RtVl;

  if (RtVl = OpenStuff())
    ProcErr(RtVl);


This part is completely broken.
 
Quote

  /* Preserve old view 2 restore it on exit */
  oldVw = GfxBase->ActiView;


Is this safe?

Quote

  if (RtVl = MkScrn ())
    ProcErr(RtVl);
  else
    { Delay (6 * TICKS_PER_SECOND);
    }


This too.

Quote

  END:
  LoadView(oldVw);
  WaitTOF();
  DestroyScrn();
  CloseStuff();
  exit(0);
}


I would just use OpenScreen() or other not so low level gfx api function...
Title: Re: GfxLibrary madness.. stack overflow WTF ?!!
Post by: itix on February 27, 2007, 01:32:00 AM
Quote

Yeah, 2 is very likely. I read the Gfx library on the RKM's a few times and today I finally rushed to mess with it Ironically there was a forum post today by the Friedens that it will be completely replaced on OS4...


No worries since your code probably would not work on anything else than AGA :-P Planar bitmaps, wtf ;-)
Title: Re: GfxLibrary madness.. stack overflow WTF ?!!
Post by: Jose on February 27, 2007, 05:51:57 PM
@itix
"No worries since your code probably would not work on anything else than AGA  Planar bitmaps, wtf"

That's on purpose8-) But it was just to try it out, for other stuff I'll probably use other compatible standard gfx calls...
Title: Re: SOLVED_GfxLibrary madness.. stack overflow WTF ?!!
Post by: Jose on February 27, 2007, 06:15:32 PM
"    int main (int argc, char **argv)
    { LONG RtVl;

    if (RtVl = OpenStuff())
    ProcErr(RtVl);
This part is completely broken"

Absolutely.... forgot to update that part after finishing the other routines ... :-o

"/* Preserve old view 2 restore it on exit */
    oldVw = GfxBase->ActiView;
Is this safe?"

I stop multitasking 1st. I wanted to present the smallest code possible that still reproduced the bug ...

"     if (RtVl = MkScrn ())
    ProcErr(RtVl);
    else
    { Delay (6 * TICKS_PER_SECOND);
    }
This too."

forbid /permit...

"END:
    LoadView(oldVw);
    WaitTOF();
    DestroyScrn();
    CloseStuff();
    exit(0);
    }
I would just use OpenScreen() or other not so low level gfx api function..."

I want to preserve as much chip ram as possible, I'm assuming this will allow me to do that better (will also have to kill other screens too).
But probably the additional space that intuition takes is not much bigger (or at least not in chip ram). Will have to look at this in more detail later...
Title: Re: SOLVED_GfxLibrary madness.. stack overflow WTF ?!!
Post by: itix on March 01, 2007, 01:24:32 AM
Quote

I want to preserve as much chip ram as possible, I'm assuming this will allow me to do that better (will also have to kill other screens too).
But probably the additional space that intuition takes is not much bigger (or at least not in chip ram). Will have to look at this in more detail later...


Intuition screens take the same amount if chip ram. You could call CloseWorkbench() to get rid of Workbench screen but usually it is not desired and such techniques are usable only on floppy systems...

Or just kill the OS and bang HW directly :-)