Sign in to follow this  
programering

Absent breakpoint triggered while debugging

Recommended Posts

programering    105
I've encountered a breakpoint problem while debugging my/a SDL application. It breaks in the call of SDL_FreeSurface() in updateSurface() pointed by the green arrow.
bool Sprite::updateSurface()
{
	// WIP:

	if (surface)
		SDL_FreeSurface(surface);   // <-- Here.

	int depth;

	switch (bytesPP)
	{
	case 1:
		depth = 8;
		break;
	case 2:
		depth = 16;
		break;
	case 3:
		depth = 24;
		break;
	case 4:
		depth = 32;
		break;
	default:
		depth = 0;
		break;
	}

	surface = SDL_CreateRGBSurface(0,width,height,depth,0x00ff0000,0x0000ff00,0x000000ff,0x00000000);
	if (!surface)
		return false;

	/* Lock the screen for direct access to the pixels */
    if (SDL_MUSTLOCK(surface))
	{
        if (SDL_LockSurface(surface) < 0)
		{
            SDL_GetError();
            return false;
        }
    }

	Uint8 *pixel = (Uint8 *) surface->pixels;
	Uint32 *write;

	for (Uint32 i = 0; i < pixelCount; i++)
	{
		write = (Uint32 *) pixel;
		*write = pixels[i*bytesPP];
		pixel += bytesPP;
	}

	if (SDL_MUSTLOCK(surface))
		SDL_UnlockSurface(surface);

	return true;
}
test.cpp:
#include "SDL.h"
#include "sprite.h"


Sprite sprite(100,2);
SDL_Surface *screen;
SDL_Event event;
int x, y;


int main(int argc, char *argv[])
{
	SDL_Init(SDL_INIT_VIDEO);

	screen = SDL_SetVideoMode(640,480,32,0);
	SDL_WM_SetCaption("Sprite Test",NULL);

	bool running = true;

	while (running)
	{
		if (SDL_PollEvent(&event))
		{
			switch (event.type)
			{
			case SDL_QUIT:
				running = false;
				break;
			case SDL_MOUSEBUTTONDOWN:
				SDL_GetMouseState(&x,&y);
				sprite.setPixel(x,y,0xffffffff);
				break;
			default:
				break;
			}
		}
		sprite.display(screen,0,0);
		SDL_UpdateRect(screen,0,0,0,0);
	}


	return 0;
}




sprite.h:
#ifndef BASECODE_CPP_SDL_VIDEO_HEADER_SPRITE
#define BASECODE_CPP_SDL_VIDEO_HEADER_SPRITE

#include "SDL_video.h"



class Sprite
{
public:
	// Constructor(s):
	Sprite();
	Sprite(Uint16 size, Uint8 bypp);
	Sprite(Uint16 width, Uint16 height, Uint8 bypp);
	// Initialize:
	void init();
	// Create:
	bool create(Uint16 size, Uint8 bypp);
	bool create(Uint16 width, Uint16 height, Uint8 bypp);
	// Enlarge by x 2:
	bool enlarge();
	// Set:
	bool setPixel(Uint16 x, Uint16 y, Uint32 pix);
	// Display:
	bool display(SDL_Surface *dest, short x, short y);
	// Read from source & write to destination:
	bool readFrom(SDL_Surface *src, SDL_Rect *srcRect);
	bool writeTo(SDL_Surface *dest, SDL_Rect *dstRect);
	bool writeTo(SDL_Surface *dest, SDL_Rect *dstRect, SDL_Rect *srcRect);
	// Get:
	SDL_Surface *getSurface();
	// Destructor:
	~Sprite();
private:
	// Internal members:
	bool alloc();
	void free();
	bool updateSurface();
	
	Uint16 width;
	Uint16 height;
	Uint32 pixelCount;
	Uint8 bytesPP;
	Uint32 pixelsSize;
	Uint8 *pixels;
	SDL_Surface *surface;
	bool success;
};




#endif




sprite.cpp:
#include "sprite.h"



//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Constructor(s):

Sprite::Sprite()
{
	init();
}


Sprite::Sprite(Uint16 size, Uint8 bypp)
{
	init();
	success = create(size,bypp);
}


Sprite::Sprite(Uint16 width, Uint16 height, Uint8 bypp)
{
	init();
	success = create(width,height,bypp);
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Initialize:

void Sprite::init()
{
	pixels = NULL;
	surface = NULL;
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Create functions:

bool Sprite::create(Uint16 size, Uint8 bypp)
{
	return create(size,size,bypp);
}


bool Sprite::create(Uint16 width, Uint16 height, Uint8 bypp)
{
	this->width = width;
	this->height = height;
	pixelCount = width * height;
	bytesPP = bypp;
	pixelsSize = pixelCount * bytesPP;

	if (!alloc())
		return false;

	updateSurface();
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Update the display surface:

bool Sprite::updateSurface()
{
	// WIP:

	if (surface)
		SDL_FreeSurface(surface);  // <-- Here.

	int depth;

	switch (bytesPP)
	{
	case 1:
		depth = 8;
		break;
	case 2:
		depth = 16;
		break;
	case 3:
		depth = 24;
		break;
	case 4:
		depth = 32;
		break;
	default:
		depth = 0;
		break;
	}

	surface = SDL_CreateRGBSurface(0,width,height,depth,0x00ff0000,0x0000ff00,0x000000ff,0x00000000);
	if (!surface)
		return false;

	/* Lock the screen for direct access to the pixels */
    if (SDL_MUSTLOCK(surface))
	{
        if (SDL_LockSurface(surface) < 0)
		{
            SDL_GetError();
            return false;
        }
    }

	Uint8 *pixel = (Uint8 *) surface->pixels;
	Uint32 *write;

	for (Uint32 i = 0; i < pixelCount; i++)
	{
		write = (Uint32 *) pixel;
		*write = pixels[i*bytesPP];
		pixel += bytesPP;
	}

	if (SDL_MUSTLOCK(surface))
		SDL_UnlockSurface(surface);

	return true;
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Enlarge by x 2:

bool Sprite::enlarge()
{
	// TODO:
	return false;
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Set:

bool Sprite::setPixel(Uint16 x, Uint16 y, Uint32 pix)
{
	// WIP:
	if (x < width && y < height)
	{
		pixels[y * surface->pitch + x * bytesPP] = pix;
	}
	else
		return false;

	return updateSurface();
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Display:

bool Sprite::display(SDL_Surface *dest, short x, short y)
{
	// TODO:
	if (SDL_BlitSurface(surface,NULL,dest,NULL))
		return false;

	return true;
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Read from source & write to destination:
/*
bool Sprite::readFrom(SDL_Surface *src, SDL_Rect *srcRect)
{
	// TODO:
}


bool Sprite::writeTo(SDL_Surface *dest, SDL_Rect *dstRect)
{
	// TODO:
}


bool Sprite::writeTo(SDL_Surface *dest, SDL_Rect *dstRect, SDL_Rect *srcRect)
{
	// TODO:
}
*/

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Get:

SDL_Surface *Sprite::getSurface()
{
	return surface;
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Free function:

bool Sprite::alloc()
{
	if (pixels)
	{
		// Free first:
		free();
		// Or fail:
	//	return false;
	}

	pixels = new Uint8[pixelsSize];

	if (pixels)
		return true;
	else
		return false;
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Free function:

void Sprite::free()
{
	if (pixels)
		delete [] pixels;

	if (surface)
		SDL_FreeSurface(surface);
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Destructor:

Sprite::~Sprite()
{
	free();
}





The output information:
'Sprite.exe': Loaded 'C:\Projects\Programming\Sprite\Debug\Sprite.exe', Symbols loaded.
'Sprite.exe': Loaded 'C:\Windows\System32\ntdll.dll'
'Sprite.exe': Loaded 'C:\Windows\System32\kernel32.dll'
'Sprite.exe': Loaded 'C:\Windows\system\SDL.dll', Binary was not built with debug information.
'Sprite.exe': Loaded 'C:\Windows\System32\advapi32.dll'
'Sprite.exe': Loaded 'C:\Windows\System32\rpcrt4.dll'
'Sprite.exe': Loaded 'C:\Windows\System32\gdi32.dll'
'Sprite.exe': Loaded 'C:\Windows\System32\user32.dll'
'Sprite.exe': Loaded 'C:\Windows\System32\msvcrt.dll'
'Sprite.exe': Loaded 'C:\Windows\System32\winmm.dll'
'Sprite.exe': Loaded 'C:\Windows\System32\ole32.dll'
'Sprite.exe': Loaded 'C:\Windows\System32\oleaut32.dll'
'Sprite.exe': Loaded 'C:\Windows\System32\oleacc.dll'
'Sprite.exe': Loaded 'C:\Windows\winsxs\x86_microsoft.vc90.debugcrt_1fc8b3b9a1e18e3b_9.0.30729.1_none_bb1f6aa1308c35eb\msvcr90d.dll'
'Sprite.exe': Loaded 'C:\Windows\System32\shimeng.dll'
'Sprite.exe': Loaded 'C:\Windows\System32\apphelp.dll'
'Sprite.exe': Loaded 'C:\Windows\AppPatch\AcLayers.dll'
'Sprite.exe': Loaded 'C:\Windows\System32\shell32.dll'
'Sprite.exe': Loaded 'C:\Windows\System32\shlwapi.dll'
'Sprite.exe': Loaded 'C:\Windows\System32\userenv.dll'
'Sprite.exe': Loaded 'C:\Windows\System32\secur32.dll'
'Sprite.exe': Loaded 'C:\Windows\System32\winspool.drv'
'Sprite.exe': Loaded 'C:\Windows\System32\mpr.dll'
'Sprite.exe': Loaded 'C:\Windows\System32\imm32.dll'
'Sprite.exe': Loaded 'C:\Windows\System32\msctf.dll'
'Sprite.exe': Loaded 'C:\Windows\System32\lpk.dll'
'Sprite.exe': Loaded 'C:\Windows\System32\usp10.dll'
'Sprite.exe': Loaded 'C:\Windows\System32\avgrsstx.dll'
'Sprite.exe': Loaded 'C:\Windows\winsxs\x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.6002.18005_none_5cb72f96088b0de0\comctl32.dll'
'Sprite.exe': Loaded 'C:\Windows\System32\ddraw.dll'
'Sprite.exe': Loaded 'C:\Windows\System32\dciman32.dll'
'Sprite.exe': Loaded 'C:\Windows\System32\setupapi.dll'
'Sprite.exe': Loaded 'C:\Windows\System32\dwmapi.dll'
'Sprite.exe': Unloaded 'C:\Windows\System32\ddraw.dll'
'Sprite.exe': Unloaded 'C:\Windows\System32\dwmapi.dll'
'Sprite.exe': Unloaded 'C:\Windows\System32\setupapi.dll'
'Sprite.exe': Unloaded 'C:\Windows\System32\dciman32.dll'
'Sprite.exe': Loaded 'C:\Windows\System32\KBDUS.DLL'
'Sprite.exe': Unloaded 'C:\Windows\System32\KBDUS.DLL'
'Sprite.exe': Loaded 'C:\Windows\System32\KBDSW.DLL'
'Sprite.exe': Unloaded 'C:\Windows\System32\KBDSW.DLL'
HEAP[Sprite.exe]: Heap block at 00A22F60 modified at 00A27D88 past requested size of 4e20
Windows has triggered a breakpoint in Sprite.exe.

This may be due to a corruption of the heap, which indicates a bug in Sprite.exe or any of the DLLs it has loaded.

This may also be due to the user pressing F12 while Sprite.exe has focus.

The output window may have more diagnostic information.
HEAP[Sprite.exe]: Invalid address specified to RtlFreeHeap( 00A20000, 00A22F68 )
Windows has triggered a breakpoint in Sprite.exe.

This may be due to a corruption of the heap, which indicates a bug in Sprite.exe or any of the DLLs it has loaded.

This may also be due to the user pressing F12 while Sprite.exe has focus.

The output window may have more diagnostic information.
HEAP[Sprite.exe]: Heap block at 00A29548 modified at 00A2E370 past requested size of 4e20
Windows has triggered a breakpoint in Sprite.exe.

This may be due to a corruption of the heap, which indicates a bug in Sprite.exe or any of the DLLs it has loaded.

This may also be due to the user pressing F12 while Sprite.exe has focus.

The output window may have more diagnostic information.
HEAP[Sprite.exe]: Invalid address specified to RtlFreeHeap( 00A20000, 00A29550 )
Windows has triggered a breakpoint in Sprite.exe.

This may be due to a corruption of the heap, which indicates a bug in Sprite.exe or any of the DLLs it has loaded.

This may also be due to the user pressing F12 while Sprite.exe has focus.

The output window may have more diagnostic information.
HEAP[Sprite.exe]: Heap block at 02600040 modified at 02604E68 past requested size of 4e20
Windows has triggered a breakpoint in Sprite.exe.

This may be due to a corruption of the heap, which indicates a bug in Sprite.exe or any of the DLLs it has loaded.

This may also be due to the user pressing F12 while Sprite.exe has focus.

The output window may have more diagnostic information.


How do I solve this?

Share this post


Link to post
Share on other sites
jpetrie    13103
See the part that says:
Quote:

HEAP[Sprite.exe]: Heap block at 00A22F60 modified at 00A27D88 past requested size of 4e20


That means you wrote past the end of the allocated memory for the buffer in question. This sort of thing is generally detected when the allocated memory is released, which is happening inside the SDL_FreeSurface call.

Chances you are computing the size of the buffer incorrectly when you're trying to copy data to the surface, or something. Look at your for loop carefully.

Share this post


Link to post
Share on other sites
outRider    852

HEAP[Sprite.exe]: Heap block at 00A22F60 modified at 00A27D88 past requested size of 4e20

HEAP[Sprite.exe]: Invalid address specified to RtlFreeHeap( 00A20000, 00A22F68 )


You have memory corruption.

Start commenting out blocks of code until it starts working.

I didn't take a close look at your code but this jumped out at me:


if (x < width && y < height)
{
pixels[y * surface->pitch + x * bytesPP] = pix;
}


Why are you using surface->pitch? The pitch of pixels[] is not guaranteed to be the same as the pitch of the SDL surface.


Uint8 *pixel = (Uint8 *) surface->pixels;
Uint32 *write;

for (Uint32 i = 0; i < pixelCount; i++)
{
write = (Uint32 *) pixel;
*write = pixels[i*bytesPP];
pixel += bytesPP;
}


Why are you NOT using surface->pitch? The pitch of the SDL surface is not guaranteed to be width*bytesPP.

Share this post


Link to post
Share on other sites
programering    105
I was just using the surface->pitch temporarly, and I'll fix this.

The memory write coruption must be here:

*write = pixels[i*bytesPP];

in the middle line of the for loop.

Share this post


Link to post
Share on other sites
programering    105
I can't directly see anything wrong with this code:

Uint8 *pixel = (Uint8 *) surface->pixels;
Uint32 *write;

for (Uint32 i = 0; i < pixelCount; i++)
{
write = (Uint32 *) pixel;
*write = pixels[i*bytesPP];
pixel += bytesPP;
}


... because the 'pixel' is of one byte that gets increased by 'bytesPP' which currently is two. The only thing that I can think of is at the end when the last '*write' assignments or the last ones go out of its scope.

Edit:
Yes when I try to set: if (i < pixelCount-1) before that assignment it don't crashes like that.


// Don't crashes:
if (i < pixelCount-1)
*write = pixels[i*bytesPP];

. . .

if (i < pixelCount) // <-- But this does.
*write = pixels[i*bytesPP];


Thanks both for your help. rate+. (Edit2: Had no effect, unfortunatly.)

[Edited by - programering on April 6, 2010 8:59:49 AM]

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this