Crash When Calling Accessor

Discuss the development of new homebrew software, tools and libraries.

Moderators: cheriff, TyRaNiD

Post Reply
User avatar
lokust
Posts: 22
Joined: Sun May 28, 2006 7:34 am

Crash When Calling Accessor

Post by lokust »

I have the following acessors in my class, the first set crashes the PSP whenever I call it:

Code: Select all

const ScePspFVector2 GetTopLeftUV()  const;
const ScePspFVector2 GetBottomRightUV() const;

const ScePspFVector2 CSprite::GetTopLeftUV()  const
{
	const ScePspFVector2 uv = {m_TexCoords.x, m_TexCoords.y}; 
	return uv;
}
const ScePspFVector2 CSprite::GetBottomRightUV() const
{
	const ScePspFVector2 uv = {m_TexCoords.z, m_TexCoords.w}; 
	return uv;
}
However this one works ok:

Code: Select all

const ScePspFVector4 &GetImageCoords() const { return m_TexCoords; }
I am really clueless about whats going on here. I writeback all the data in cache at the beginning of each frame. Is there something else I should be aware of?
PeterM
Posts: 125
Joined: Sat Dec 31, 2005 7:25 pm
Location: Edinburgh, UK
Contact:

Post by PeterM »

Hmm weird one. Is the 'this' pointer null?
User avatar
lokust
Posts: 22
Joined: Sun May 28, 2006 7:34 am

Post by lokust »

PeterM wrote:Hmm weird one. Is the 'this' pointer null?
Nope, otherwise the second should crash just the same Im pretty sure.
User avatar
lokust
Posts: 22
Joined: Sun May 28, 2006 7:34 am

Post by lokust »

And apparently this is becoming an issue with every class I write. Acessors crash. Anyone else writing C++ code for the PSP?
Last edited by lokust on Thu Jun 15, 2006 11:49 pm, edited 1 time in total.
PeterM
Posts: 125
Joined: Sat Dec 31, 2005 7:25 pm
Location: Edinburgh, UK
Contact:

Post by PeterM »

Not if it's just returning a reference, but yes if you dereference that reference.
User avatar
lokust
Posts: 22
Joined: Sun May 28, 2006 7:34 am

Post by lokust »

PeterM wrote:Not if it's just returning a reference, but yes if you dereference that reference.
Its just returning a reference. I have this same problem with this simple acessor in a timer class:

Code: Select all

const u32 &GetTickRes() const { return m_iTickRes; }
I have tried inlining, not inlining, returning const referece, returning reference, returning value, and making the function non-const. Sometimes I get serious graphical errors, other times the psp just shuts off.

Stumped.
User avatar
lokust
Posts: 22
Joined: Sun May 28, 2006 7:34 am

Post by lokust »

It appears sometimes it is if I call the accessor more than once, if I call it once and save the value, then use that _sometimes_ it works.
User avatar
lokust
Posts: 22
Joined: Sun May 28, 2006 7:34 am

Post by lokust »

Here is my entire render loop:

Code: Select all

while(!done)
	{
		sceKernelDcacheWritebackInvalidateAll();
		mySprite->SetTopLeftUV(mySprite->GetImageCoords().x+5.0f,mySprite->GetImageCoords().y);
		mySprite->SetBottomRightUV(mySprite->GetImageCoords().z+5.0f,mySprite->GetImageCoords().w);
		mySprite->SetPosition(xPos,yPos);
		mySprite->Rotate(u*.01);
	
		pspRenderer->BeginDraw();
			pspRenderer->ClearScreen();
			pspRenderer->Ortho();
			
			sceGuTexImage(0,myImage->iTexWidth,myImage->iTexHeight,myImage->iTexWidth,(void*)myImage->pData);	
			sceGuTexScale(1.0f/(float)myImage->iTexWidth,1.0f/(float)myImage->iTexHeight);
			
			pspRenderer->DrawSprite(*mySprite);
		pspRenderer->EndDraw();

		iFrameCount++;
		//u32 tickRes = time.GetTickRes();
		//u64 elapsedTime = time.GetElapsedTime();
		static float fps = 0.0f;
		if(time.GetElapsedTime() >= time.GetTickRes())
		{
			fps = 1.0f / fCurMs;

			double span  = time.GetElapsedTime() / time.GetTickRes();
			fCurMs = span / iFrameCount;

			time.Reset();
			iFrameCount = 0;
		}
		pspDebugScreenSetXY(5,5);
		printf("%f",fps);
		
		pspRenderer->RenderScene();
	}
What is interesting is if I change this section here:

Code: Select all

iFrameCount++;
		//u32 tickRes = time.GetTickRes();
		//u64 elapsedTime = time.GetElapsedTime();
		static float fps = 0.0f;
		if(time.GetElapsedTime() >= time.GetTickRes())
		{
			fps = 1.0f / fCurMs;

			double span  = time.GetElapsedTime() / time.GetTickRes();
			fCurMs = span / iFrameCount;

			time.Reset();
			iFrameCount = 0;
		}
		pspDebugScreenSetXY(5,5);
		printf("%f",fps);
		
		pspRenderer->RenderScene();
to this:

Code: Select all

iFrameCount++;
		u32 tickRes = time.GetTickRes();
		//u64 elapsedTime = time.GetElapsedTime();
		static float fps = 0.0f;
		if(time.GetElapsedTime() >= time.GetTickRes())
		{
			fps = 1.0f / fCurMs;

			double span  = time.GetElapsedTime() / tickRes;
			fCurMs = span / iFrameCount;

			time.Reset();
			iFrameCount = 0;
		}
		pspDebugScreenSetXY(5,5);
		printf("%f",fps);
		
		pspRenderer->RenderScene();
It works, otherwise I get strange graphical error, or the PSP shuts down. Am I handling the cache properly? Should I be writing cache back somewhere? I have tried after the graphics calls (after pspRenderer->RenderScene()), but that didt fix.
User avatar
Raphael
Posts: 646
Joined: Tue Jan 17, 2006 4:54 pm
Location: Germany
Contact:

Post by Raphael »

Just a quick guess: Check for fCurMs and tickRes to be != 0 to get sure. However, tickRes should be a constant, no?
Btw: is GetTickRes() and GetElapsedTime() returning a u32/u64 or float?
User avatar
lokust
Posts: 22
Joined: Sun May 28, 2006 7:34 am

Post by lokust »

Raphael wrote:Just a quick guess: Check for fCurMs and tickRes to be != 0 to get sure. However, tickRes should be a constant, no?
Btw: is GetTickRes() and GetElapsedTime() returning a u32/u64 or float?
Yes, ideally tickRes would be constant (well, ideally I wouldnt need it at all), however I was playing with return values and such to see what happened. GetElapsedTime returns a float.

My latest attempt seems to work, but I am still not sure why. I create the object on the heap using the new operator. I guess there may not have been enough room on the stack? I also tried declaring it in the global namespace, but that had the same problems. Think I might be missing some detail here.

EDIT: Oh, and the algorithm works, it prints the correct FPS (when it works somewhat) but the image is completely messed up. Sometimes it also just crashes.
User avatar
Raphael
Posts: 646
Joined: Tue Jan 17, 2006 4:54 pm
Location: Germany
Contact:

Post by Raphael »

lokust wrote:
Raphael wrote: Btw: is GetTickRes() and GetElapsedTime() returning a u32/u64 or float?
GetElapsedTime returns a float.
Well, my guess was that in the one case, where you typecast the GetTickRes to u32, the rounding of a int divide will keep the span and thus the fCurMs from becoming 0, which would cause a crash. But that's idiotic alltogether, since then it should be the other way around (int div rounding down to zero more likely).
In either case, checking for divisors to be non-zero should be done to get on the safe side in every case.
User avatar
lokust
Posts: 22
Joined: Sun May 28, 2006 7:34 am

Post by lokust »

Raphael wrote:In either case, checking for divisors to be non-zero should be done to get on the safe side in every case.
Yeah, I suppose I should do that ;) But wouldnt a dbz always crash, and not just produce strange graphical errors?
User avatar
Raphael
Posts: 646
Joined: Tue Jan 17, 2006 4:54 pm
Location: Germany
Contact:

Post by Raphael »

lokust wrote: Yeah, I suppose I should do that ;) But wouldnt a dbz always crash, and not just produce strange graphical errors?
That's true :) Most graphical issues are cache-related, though I also had one or two cases in which this definitely wasn't the case and only the aproach of completely rewriting some code parts helped.
Allotgether, PSP dev seems to be much more open to random missbehaviour than PC development :)
User avatar
lokust
Posts: 22
Joined: Sun May 28, 2006 7:34 am

Post by lokust »

Raphael wrote:Allotgether, PSP dev seems to be much more open to random missbehaviour than PC development :)
So I am learning ;)

Any idea why creating the CTime object on the heap would fix the problem? Maybe dodged some cache mishandling that way?
SSpeare
Posts: 63
Joined: Tue May 23, 2006 11:45 pm
Contact:

Post by SSpeare »

Getting the proper constructors and such to run for C++ objects that are staticly instantiated can often be a difficulty if the C++ compiler/environment isn't all that great. There is a function that is supposed to do that for you called __ctor or something like that (that name might be way off).

The order of those operations can really be messy, so it's always safer on a less stable toolchain to create things using the heap. It shouldn't be a problem for objects created on the stack at runtime, just those created outside of any function.

From what I've heard and known, C++ development on SONY consoles has not been too favorably looked upon. It works on PS2 today, but the early compilers were C only.

(This is all just conjecture though.... Maybe I shouldn't post it....)
User avatar
groepaz
Posts: 305
Joined: Thu Sep 01, 2005 7:44 am
Contact:

Post by groepaz »

problem might be that on fw2.0+ the global constructors dont get called (see eloader docs for details), so you gotta call them manually.
User avatar
lokust
Posts: 22
Joined: Sun May 28, 2006 7:34 am

Post by lokust »

SSpeare wrote:(This is all just conjecture though.... Maybe I shouldn't post it....)
No, thank you! That's good info, I will look into it a bit more.
groepaz wrote:problem might be that on fw2.0+ the global constructors dont get called (see eloader docs for details), so you gotta call them manually.
Also interesting, I am however running 1.5.
User avatar
dot_blank
Posts: 498
Joined: Wed Sep 28, 2005 8:47 am
Location: Brasil

Post by dot_blank »

sceKernelDcacheWritebackInvalidateAll(); should be at end of
drawing loop

also shouldnt this be outside of while loop -> static float fps = 0.0f;
10011011 00101010 11010111 10001001 10111010
Post Reply