forums.ps2dev.org Forum Index forums.ps2dev.org
Homebrew PS2, PSP & PS3 Development Discussions
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Very wierd program behaviour - Compiler bugs?

 
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PSP Development
View previous topic :: View next topic  
Author Message
Kojima



Joined: 26 Jun 2006
Posts: 275

PostPosted: Wed Aug 09, 2006 7:22 pm    Post subject: Very wierd program behaviour - Compiler bugs? Reply with quote

Hi,

I'm experiencing very wierd behaviour in my C++ psp app. (Raptor)

For example if I do this,

Code:

   
   ParticleEngine * pe = new ParticleEngine( NULL,1000 );
   


it runs fine. I can see my particles on screen and it does not crash.

But if I change it to this,

Code:


         Texture *ftex = new Texture("flare.jpg",JPEG);
   ParticleEngine * pe = new ParticleEngine( ftex,1000 );
   


It crashes in the particle engine call.

But , and this is where it gets really wierd.. If I add two calls to my log system within the particleengine constructor, one at the top, and one at the bottom, trying to pinpoint where it crashes.
It no longer crashes. But now my framerate(A counter at the top of the screen) firmly stays at ZERO, and the screen is blank.

This is the second time this has happened. I added a terrain engine to raptor recently, and if I call it before loading a b3d, the b3d call fails and crashes. but when I added logger calls to the b3d load, it no longer crashes.

The result of this is an impossible to trace crash point.

Here's the full code to the demo as it crashes, it's very simple with very little logic.

Code:

int main(int argc, char **argv)
{   
   pspDebugScreenInit();

   InitRaptor();

   Joypad *joy = new Joypad;

   SetDefaultStyle( new GradientStyle );
   Display *sys = new Display(argc,argv);
   Pen *pen = new Pen;
   
    Camera *vcam = Factory->ProduceCamera();
 
    vcam->Position(0,40,-20);
 
   Renderer->_ActiveCam = vcam;
   vcam->PointAt(0,0,0);
   
   float bx,by;
   bx=0;
   by=0;
   glDisable( GL_CULL_FACE );

   Font *fnt = new Font("fnt1.bmp",32,32);
    FontRenderer->SetActive( fnt );
    FontRenderer->SetColor(1,1,1);
   char * yawtxt = NULL;
   char * angtxt = NULL;
   int mode;
   mode = m_play;
    float cx,cy;
    cx=0;
    cy=0;
 float ex=0;


  u64 fp_lms;
  int fp_frms;
   int fp_fps;
   int fp_first = true;

   int lm = sceRamLeft();
   float frame=1;
   Logger->Log("Entering Main Loop.\n");
   Texture *ftex = new Texture("flare.jpg",JPEG);
   Logger->Log("Creating PE\n");
   ParticleEngine * pe = new ParticleEngine( ftex,1000 );
   
   Particle * ep = pe->Emit( 5,0,0,0,0,0 );
   pe->Emit( 3,-2,0,0,0,0 );
   pe->Emit( 7,-1,0,0,0,0 );
   vcam->Position( 0,20,0 );
   vcam->PointAt( 0,0,0 );
   Logger->Log("Entering Main Loop.\n");

    while(1)
 
  {

     for(int i=0;i<10;i++)
     {
     pe->Emit( 0,0,0,( -5+rand()%10 ) ,0,(-5+rand()%10)  );
     };   
     pe->Update();
         
 
        frame++;
        if(frame>199) frame=1;

       u64 ms = GetTick();
       if( (ms<fp_lms) || (fp_first == true) )
       {
          fp_fps = fp_frms;
          fp_frms=0;
          fp_lms=ms-1000;
          fp_first = false;
       }
       fp_frms++;
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);   
      j
oy->Update();
       
       float xi,yi;
       xi = joy->_x;
       yi = joy->_y;
       
       if(fabs(xi)>0.4)
       {
          cx+=xi;
       }
       if(fabs(yi)>0.4)
       {
          cy+=yi;
       }
          
    
       if(cy>360) cy=0;
    
       Renderer->RenderScene();     
           
       Blend_Mask();
       sys->Draw2D();
       if( !(yawtxt == NULL ) )
       {
          free( (void *)yawtxt );
       }
       yawtxt = StringUtil->Num( fp_fps );
       FontRenderer->RenderText(0,0,yawtxt);
       Blend_Solid();

      if(joy->_select==1)
      {
         CloseRaptor();
         sceKernelExitGame();
      }
     if( joy->_rtrigger )
     {
        screenshot("mplay");
     }
     glutSwapBuffers();

  }

  return (0);
}



And here's my makefile. In case anything I've done in that could be causing the strange behaviour.

Code:

TARGET = lesson2
OBJS = main.o

CFLAGS = -G0 -Wall
CXXFLAGS = $(CFLAGS) -fno-exceptions
ASFLAGS = $(CFLAGS)
   
PSPBIN = $(PSPSDK)/../bin
CFLAGS += -I$(PSPSDK)/../include  -fsingle-precision-constant -g 
LIBS +=  -llua -lz  -lpspgu -ljpeg -lpng -lz -losl -lpspgu -lmikmod -lpspaudio -lGLU -lglut -lGLU -lGL -llualib -llua -lm -lc -lpsputility -lpspdebug -lpspge -lpspdisplay -lpspctrl -lpspsdk -lpspvfpu -lpsplibc -lpspuser -lpspkernel -lpsprtc -lpsppower -lstdc++ -llua
LDFLAGS += -DMODULE_NAME="Raptor Alpha" psp-setup.c



EXTRA_TARGETS = EBOOT.PBP
PSP_EBOOT_TITLE = Raptor Test
# PSP_EBOOT_ICON = hero.png
# PSP_EBOOT_PIC1 = bg.png


PSPSDK=$(shell psp-config --pspsdk-path)
include $(PSPSDK)/lib/build.mak


If it makes a difference, I'm using the jun2nd build of xorloser prebuilt psp toolchain. with svn versions of pspgl,mikmok and lua.

Any help would be appreciated as this is just something I've never seen before. I've coded a million apps on the pc and never run into this before.
Back to top
View user's profile Send private message
Kojima



Joined: 26 Jun 2006
Posts: 275

PostPosted: Wed Aug 09, 2006 7:43 pm    Post subject: Reply with quote

I just tried,

Code:

   Texture *ftex = new Texture("flare.jpg",JPEG);
   Logger->Log("Creating PE\n");
   ParticleEngine * pe = new ParticleEngine( NULL,1000 );
   


Which loads the texture but does not assign, and now I see the particles again BUT they are all skewed and it's like an almost isometric view. (The camera is directlly above them)

I remove the load texture call and like magic it appears normal again.

It really cannot be the texture code causing this, as I've tried both bmp and jpg textures, both of which use different methods of loading.

So it could either be A) a compiler bug. B) a pspGL bug or C) human error.

I also tried various make file combinations, like o2 optimization, removing wall, removing just about every option one by one, but nothing made the slightest bit of difference.


Last edited by Kojima on Wed Aug 09, 2006 7:45 pm; edited 1 time in total
Back to top
View user's profile Send private message
danzel



Joined: 04 Nov 2005
Posts: 182

PostPosted: Wed Aug 09, 2006 7:44 pm    Post subject: Reply with quote

Me 2!

I had a function that read from a file character by character and did some pointer arithmetic to put it in a char* and it had a complete stop somewhere in there with no exceptions, when I added some debug printfs it started working.
In the end I made it use indexing instead of pointer arithmetic and it worked.
Strange times....

Maybe you could step through it with psplink/gdb to work out whats happening?
Back to top
View user's profile Send private message
Kojima



Joined: 26 Jun 2006
Posts: 275

PostPosted: Wed Aug 09, 2006 7:47 pm    Post subject: Reply with quote

Ah if only, psplink doesn't work for me. I think because my pc has usb1.1 instead of 2.0.

So it could be pointers causing the problem huh? Have to admit I don't like the idea of replacing my pointers..In fact I don't even think I could, not without major major redesigns and going back to C which is just ugh..:)
Back to top
View user's profile Send private message
ReKleSS



Joined: 18 Jun 2005
Posts: 73
Location: Melbourne, Australia

PostPosted: Wed Aug 09, 2006 8:07 pm    Post subject: Reply with quote

1) USB version makes no difference. USB 1.1 is 12Mbps; USB2 is 480Mbps (yeah right...). psplink will work.

2) Your error sounds like memory getting trampled on. Take a careful look around. You're probably overrunning an array or something.
Back to top
View user's profile Send private message
Kojima



Joined: 26 Jun 2006
Posts: 275

PostPosted: Wed Aug 09, 2006 8:21 pm    Post subject: Reply with quote

Nah search the forums, there are quite a few cases of people with usb1.1 having problems with osolink.
I did try it, compiled all the pc side apps etc, but as soon as it connects it trashes the usb connection and I have to reboot the pc to use usb again.

As for overrunning an array etc, I doubt it as there are no arrays, so it leaves only malloced space. Which is probable but I have checked and found no problems.
I'll have another look to be sure though.
Back to top
View user's profile Send private message
Raphael



Joined: 17 Jan 2006
Posts: 646
Location: Germany

PostPosted: Wed Aug 09, 2006 8:56 pm    Post subject: Reply with quote

ReKless is most likely right. All my weird behaviour bugs I had up to now, resolved to me somewhere over/underrunning a buffer. Then only one totally different line in the code would change the crash behaviour completely.
So your buffer overrun could be in the texture loader, but doesn't need to. If you can't find it by yourself, probably try with the memory manager I already suggested somewhere here. It's also helpful to track buffer over/underruns, as it signs all allocated memory areas at beginning and end, so when these change you know which buffer was over/underrun.
_________________
<Don't push the river, it flows.>
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki

Alexander Berl
Back to top
View user's profile Send private message Visit poster's website
Kojima



Joined: 26 Jun 2006
Posts: 275

PostPosted: Wed Aug 09, 2006 10:47 pm    Post subject: Reply with quote

You maybe right, although I managed to locate the source of the problem.
JPEG textures. I kludged my b3d loader to use the bmp loader when finding jpegs, and replaced zombie.jpg with a bmp by the same name, and now it works fine.

So it appears either the jpeg library is broken, or I've made a mistake in my loader.

Here it is, if anyone has experience with the loader I'd appreciate any pointers you may have.

Code:


class JpgLoader
{
public:
   JpgLoader()
   {
   }
   Img * LoadJpg(const char *file)
   {
      struct jpeg_decompress_struct cinfo;
      struct my_error_mgr jerr;
     /* More stuff */
     FILE * infile;      /* source file */
       JSAMPARRAY buffer;      /* Output row buffer */
     int row_stride;      /* physical row width in output buffer */
     if ((infile = fopen(file, "rb")) == NULL) {
       printf("Unable to load jpg %s\n", file);
       return NULL;
     }
     cinfo.err = jpeg_std_error(&jerr.pub);
     jerr.pub.error_exit = my_error_exit;
     /* Establish the setjmp return context for my_error_exit to use. */
     if (setjmp(jerr.setjmp_buffer)) {
       /* If we get here, the JPEG code has signaled an error.
        * We need to clean up the JPEG object, close the input file, and return.
        */
       jpeg_destroy_decompress(&cinfo);
       fclose(infile);
       return NULL;
     }
     /* Now we can initialize the JPEG decompression object. */
       jpeg_create_decompress(&cinfo);

     /* Step 2: specify data source (eg, a file) */
      jpeg_stdio_src(&cinfo, infile);
         
       (void) jpeg_read_header(&cinfo, TRUE);
       (void) jpeg_start_decompress(&cinfo);
      row_stride = cinfo.output_width * cinfo.output_components;
        buffer = (*cinfo.mem->alloc_sarray)
      ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
         char *imgbuf = (char *)memalign(16, cinfo.output_width*cinfo.output_height * cinfo.output_components );
      
         _buf = imgbuf;
         _w = cinfo.output_width;
         _h = cinfo.output_height;
         _c = cinfo.output_components;
         _ln = 0;
         
      while (cinfo.output_scanline < cinfo.output_height) {
       /* jpeg_read_scanlines expects an array of pointers to scanlines.
        * Here the array is only one element long, but you could ask for
        * more than one scanline at a time if that's more convenient.
        */
       (void) jpeg_read_scanlines(&cinfo, buffer, 1);
       /* Assume put_scanline_someplace wants a pointer and sample count. */
       AddScan((char *)buffer[0], row_stride);
    }
   
   
  (void) jpeg_finish_decompress(&cinfo);
     jpeg_destroy_decompress(&cinfo);
       fclose(infile);
    Img * img = new Img;
    img->_buf = _buf;
    img->_w = _w;
    img->_h = _h;
    img->_c = _c;
    return img;
           
   }
   void AddScan( char * line,int len)
   {
      char *nb = _buf;
      nb = nb + ( _ln * _w * _c );
      for(int i=0;i<len;i++)
      {
         nb[i] = line[i];
      }
      _ln++;
   }
   
   char *_buf;   
   int _w,_h,_c,_ln;
};



And here's the texture constructor that invokes it,

Code:

   Texture(char *file,ImageFormat form)
   {
   
      _coordset=0;
      _filename = file;
      char *tex;
      switch( form )
      {
         case JPEG:
            JpgLoader *jl = new JpgLoader;
            Img * img = jl->LoadJpg( (const char *) file );
            if( img == NULL )
            {
               printf("Unable to load texture\n");
               Logger->Log("Unable to load jpg %s \n",file);
               exit(0);
            }
            else
            {
               Logger->Log("Loaded jpg %s \n",file );
            }
            
            _w = img->_w;
            _h = img->_h;
            glGenTextures(1, &_gltex);
          glBindTexture(GL_TEXTURE_2D, _gltex);   // 2d texture (x and y size)
            glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
            glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
            tex = (char *)malloc(_w*_h*4);
               for(int x=0;x<_w;x++)
               {
                  for(int y=0;y<_h;y++)
                  {
                     char *b = tex+(y*_w*4)+x*4;
                     char *a = img->_buf+( ((_h-1)-y)*_w*3)+x*3;
                     b[0] = a[0];
                     b[1] = a[1];
                     b[2] = a[2];
                     int targ = (int)b[0] + (int)b[1] + (int)b[2];
                     if( targ>0 )
                     {
                        b[3] = 255;
                     }
                     else
                     {
                        b[3] = 0;
                     }
                     b[3] = targ;
                     
                  }
               }         
               
               glTexImage2D(GL_TEXTURE_2D, 0, 4, _w, _h, 0, GL_RGBA, GL_UNSIGNED_BYTE, tex);
               glBindTexture(GL_TEXTURE_2D,0);
               _raw = tex;
            break;
         case BMP:
             Image *image1;
           image1 = (Image *) malloc(sizeof(Image));
             if (image1 == NULL) {
                  printf("Error:Unable to allocate memory for texture.\n");
                  exit(0);
             }
            if (!ImageLoad(file, image1)) {
                  printf("Error:Unable to load image.\n");
                  Logger->Log("Could not load texture %s \n",file);
                  return;
               }
               Logger->Log("Loaded texture.%s \n",file);
               _w = image1->sizeX;
               _h = image1->sizeY;
             glGenTextures(1, &_gltex);
             glBindTexture(GL_TEXTURE_2D, _gltex);   // 2d texture (x and y size)
              glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
              glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
               
               tex = (char *)malloc(image1->sizeX*image1->sizeY*4);
               for(int x=0;x<image1->sizeX;x++)
               {
                  for(int y=0;y<image1->sizeY;y++)
                  {
                     char *b = tex+(y*image1->sizeX*4)+x*4;
                     char *a = image1->data+(y*image1->sizeX*3)+x*3;
                     b[0] = a[0];
                     b[1] = a[1];
                     b[2] = a[2];
                     int targ = (int)b[0] + (int)b[1] + (int)b[2];
                     if( targ>0 )
                     {
                        b[3] = 255;
                     }
                     else
                     {
                        b[3] = 0;
                     }
                     b[3] = targ;
                     
                  }
               }         
               
             glTexImage2D(GL_TEXTURE_2D, 0, 4, image1->sizeX, image1->sizeY, 0, GL_RGBA, GL_UNSIGNED_BYTE, tex);
               glBindTexture(GL_TEXTURE_2D,0);
               _raw = tex;
         break;
      }
      
         
   }


The wierd thing is though, it used to work, but now it flat out crashes everytime, even if it's just a lone call. So that would seem to point to memory getting trampled on as recless suggested.

I've had that a few times, app running ok, then not after introducing some new code that also uses malloced memory.

Ralph, did you ever convert memmgr to psp? I would like to use it, but I've never ported anything beside raptor, and I partly wrote that myself so it was a lot easier than some fancy memory debugger. :)
Back to top
View user's profile Send private message
Raphael



Joined: 17 Jan 2006
Posts: 646
Location: Germany

PostPosted: Wed Aug 09, 2006 11:16 pm    Post subject: Reply with quote

There's nothing to 'port' really, as it only uses stdc++ functions.

Quote:
Thanks, for anyone else using that version, change the line:
#include <new>
to
#include <new.h>
Then comment out #include "stdafx" and add -fexceptions to the makefile.


This should let you compile Paul Nettles original memory manager with your C++ project. Maybe I'll take a look at your jpeg loader when I find time, but I'm pretty sure there's a error somewhere.
Believe me when I say libjpeg does not have any such errors ;)
_________________
<Don't push the river, it flows.>
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki

Alexander Berl
Back to top
View user's profile Send private message Visit poster's website
Kojima



Joined: 26 Jun 2006
Posts: 275

PostPosted: Thu Aug 10, 2006 4:20 am    Post subject: Reply with quote

Sounds easy enough. I'm sure I'll still manage to mess it up of course but can't blame anyone for that :)

As for jpeg, I believe ya, I'm just not used to these sorts of bugs. Too much time using C# and blitzmax for my own good :)
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PSP Development All times are GMT + 10 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group