BUG: TerrainScenenode reinit+camera pos+render=MEMLEAK

You discovered a bug in the engine, and you are sure that it is not a problem of your code? Just post it in here. Please read the bug posting guidelines first.
Post Reply
bonsalty
Posts: 120
Joined: Thu Dec 10, 2009 1:30 pm
Location: Budapest,Hungary

BUG: TerrainScenenode reinit+camera pos+render=MEMLEAK

Post by bonsalty »

Again the problem is back and causes rising memory allocation.

The recipe:

Create a TerrainSceneNode, move the camera, render it , remove the node. All this in a loop. The interesting part is, that when I dont move the camera, the memory is stable. If I move the camera, but dont render the memory is stable. The problem occurs only if you move the camera, reinit the node and render it. Is there something missing? I have altered the terrain example to show the problem. Please dont send answers, about why I am doing this, its a test.

Code: Select all

	
scene::ICameraSceneNode* camera =	smgr->addCameraSceneNode(0,core::vector3df(0,1700.0f,0),core::vector3df(1010,0.0f,1100));

	

	for (int j=0;j<500;j++){
	scene::ITerrainSceneNode* terrain = smgr->addTerrainSceneNode(
		"../../media/terrain-heightmap.bmp",
		0,					// parent node
		-1,					// node id
		core::vector3df(0.f, 0.f, 0.f),		// position
		core::vector3df(0.f, 0.f, 0.f),		// rotation
		core::vector3df(40.f, 4.4f, 40.f),	// scale
		video::SColor ( 255, 255, 255, 255 ),	// vertexColor
		5,					// maxLOD
		scene::ETPS_17,				// patchSize
		4					// smoothFactor
		);

	terrain->setMaterialTexture(0,driver->getTexture("../../media/terrain-texture.jpg"));
	terrain->setMaterialType(video::EMT_LIGHTMAP);

			for (int i=0;i<500;i++){ // move camera forward

			camera->setPosition(core::vector3df(0+i*3,1700.0f,0)); //no camera movement no memleak
			driver->beginScene( );
			smgr->drawAll();
			env->drawAll();
			driver->endScene();
			}

	driver->removeHardwareBuffer(terrain->getRenderBuffer()); 
	terrain->remove();
	} // end for j


[/code]
Tomi
bonsalty
Posts: 120
Joined: Thu Dec 10, 2009 1:30 pm
Location: Budapest,Hungary

Post by bonsalty »

I cant get over this problem, removing textures, have also no effect. I tried to use loadheightmap instead of removing and creating a new node. Memory usage still growing rapidly with megabytes. Maybe this has to be moved to the bug reports.
Tomi
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

Maybe you have to give full working example.
bonsalty
Posts: 120
Joined: Thu Dec 10, 2009 1:30 pm
Location: Budapest,Hungary

Post by bonsalty »

Full code:

Code: Select all


int main()
{
	// ask user for driver
	video::E_DRIVER_TYPE driverType=video::EDT_DIRECT3D9;
	if (driverType==video::EDT_COUNT)
		return 1;

	irr::SIrrlichtCreationParameters params;
	params.DriverType=driverType;
	params.WindowSize=core::dimension2d<u32>(640, 480);
	IrrlichtDevice* device = createDeviceEx(params);

	if (device == 0)return 1; // could not create selected driver.

	
	video::IVideoDriver* driver = device->getVideoDriver();
	scene::ISceneManager* smgr = device->getSceneManager();
	gui::IGUIEnvironment* env = device->getGUIEnvironment();

	
	scene::ICameraSceneNode* camera =	smgr->addCameraSceneNode(0,core::vector3df(0,1700.0f,0),core::vector3df(1010,0.0f,1100));

	for (int j=0;j<500;j++){
	
	scene::ITerrainSceneNode* terrain=smgr->addTerrainSceneNode(
		"../../media/terrain-heightmap.bmp",
		0,					// parent node
		-1,					// node id
		core::vector3df(0.f, 0.f, 0.f),		// position
		core::vector3df(0.f, 0.f, 0.f),		// rotation
		core::vector3df(40.f, 4.4f, 40.f),	// scale
		video::SColor ( 255, 255, 255, 255 ),	// vertexColor
		5,					// maxLOD
		scene::ETPS_17,				// patchSize
		4					// smoothFactor
		);

	terrain->setMaterialTexture(0,driver->getTexture("../../media/terrain-texture.jpg"));
	terrain->setMaterialType(video::EMT_LIGHTMAP);

			for (int i=0;i<500;i++){ // move camera forward

			camera->setPosition(core::vector3df(0+i*3,1700.0f,0)); //no camera movement no memleak
			driver->beginScene( );
			smgr->drawAll();
			env->drawAll();
			driver->endScene();
			}
	
	driver->removeHardwareBuffer(terrain->getRenderBuffer()); 
	terrain->remove();
	} // end for j



	device->drop();
	
	return 0;
}

Im running it in Windows 7. Another interesting thing is, I get an acces violation, when calling for ctrl-alt-del , taskmanager.


Unhandled exception at 0x1005a373 in 12.TerrainRendering.exe: 0xC0000005: Access violation reading location 0xfeeeff1e.
It points to driver->beginScene( );
Tomi
randomMesh
Posts: 1186
Joined: Fri Dec 29, 2006 12:04 am

Post by randomMesh »

I tested your code on Linux with valgrind and it can't find problems with the terrain cleanup.
There are some unrelated memory leaks, though.

Code: Select all

==4129== ERROR SUMMARY: 478151 errors from 11 contexts (suppressed: 77 from 3)
==4129== malloc/free: in use at exit: 42,994 bytes in 485 blocks.
==4129== malloc/free: 3,942 allocs, 3,457 frees, 49,684,933 bytes allocated.
==4129== For counts of detected errors, rerun with: -v
==4129== searching for pointers to 485 not-freed blocks.
==4129== checked 264,156 bytes.
==4129== 
==4129== 
==4129== 4 bytes in 1 blocks are definitely lost in loss record 1 of 35
==4129==    at 0x4022D6E: malloc (vg_replace_malloc.c:207)
==4129==    by 0x4006B7B: (within /lib/ld-2.7.so)
==4129==    by 0x4007E0C: (within /lib/ld-2.7.so)
==4129==    by 0x4011B46: (within /lib/ld-2.7.so)
==4129==    by 0x400DA15: (within /lib/ld-2.7.so)
==4129==    by 0x401154D: (within /lib/ld-2.7.so)
==4129==    by 0x4439C2B: (within /lib/i686/cmov/libdl-2.7.so)
==4129==    by 0x400DA15: (within /lib/ld-2.7.so)
==4129==    by 0x443A05B: (within /lib/i686/cmov/libdl-2.7.so)
==4129==    by 0x4439B60: dlopen (in /lib/i686/cmov/libdl-2.7.so)
==4129==    by 0x40707F8: (within /usr/lib/libGL.so.1.2)
==4129==    by 0x4070BA7: driGetDriver (in /usr/lib/libGL.so.1.2)
==4129== 
==4129== 
==4129== 112 (8 direct, 104 indirect) bytes in 1 blocks are definitely lost in loss record 8 of 35
==4129==    at 0x4022E8C: realloc (vg_replace_malloc.c:429)
==4129==    by 0x4365535: (within /usr/lib/libX11.so.6.2.0)
==4129==    by 0x4366027: (within /usr/lib/libX11.so.6.2.0)
==4129==    by 0x436773F: (within /usr/lib/libX11.so.6.2.0)
==4129==    by 0x4367F87: _XlcCreateLC (in /usr/lib/libX11.so.6.2.0)
==4129==    by 0x4386E3A: _XlcDefaultLoader (in /usr/lib/libX11.so.6.2.0)
==4129==    by 0x436ECEA: _XOpenLC (in /usr/lib/libX11.so.6.2.0)
==4129==    by 0x436EDDD: _XrmInitParseInfo (in /usr/lib/libX11.so.6.2.0)
==4129==    by 0x4355F90: (within /usr/lib/libX11.so.6.2.0)
==4129==    by 0x4358027: XrmGetStringDatabase (in /usr/lib/libX11.so.6.2.0)
==4129==    by 0x433513E: (within /usr/lib/libX11.so.6.2.0)
==4129==    by 0x433537E: XGetDefault (in /usr/lib/libX11.so.6.2.0)
==4129== 
==4129== 
==4129== 448 bytes in 7 blocks are definitely lost in loss record 15 of 35
==4129==    at 0x4020C8A: memalign (vg_replace_malloc.c:460)
==4129==    by 0x4020D3E: posix_memalign (vg_replace_malloc.c:569)
==4129==    by 0x48F547A: ???
==4129==    by 0x493606D: ???
==4129==    by 0x488F972: ???
==4129==    by 0x488B3C0: ???
==4129==    by 0x404DEB3: (within /usr/lib/libGL.so.1.2)
==4129==    by 0x404E31D: glXCreateContext (in /usr/lib/libGL.so.1.2)
==4129==    by 0x8052C97: irr::CIrrDeviceLinux::createWindow() (in /home/foo/development/workspace/AnimatorTutorial/Release/AnimatorTutorial)
==4129==    by 0x8057BA6: irr::CIrrDeviceLinux::CIrrDeviceLinux(irr::SIrrlichtCreationParameters const&) (in /home/foo/development/workspace/AnimatorTutorial/Release/AnimatorTutorial)
==4129==    by 0x804FBC9: createDeviceEx (in /home/foo/development/workspace/AnimatorTutorial/Release/AnimatorTutorial)
==4129==    by 0x804EF24: main (main.cpp:14)
==4129== 
==4129== 
==4129== 1,568 (44 direct, 1,524 indirect) bytes in 1 blocks are definitely lost in loss record 17 of 35
==4129==    at 0x4022D6E: malloc (vg_replace_malloc.c:207)
==4129==    by 0x48F55DC: ???
==4129==    by 0x488BC94: ???
==4129==    by 0x40518D7: glXMakeContextCurrent (in /usr/lib/libGL.so.1.2)
==4129==    by 0x4051A62: glXMakeCurrent (in /usr/lib/libGL.so.1.2)
==4129==    by 0x8052CC1: irr::CIrrDeviceLinux::createWindow() (in /home/foo/development/workspace/AnimatorTutorial/Release/AnimatorTutorial)
==4129==    by 0x8057BA6: irr::CIrrDeviceLinux::CIrrDeviceLinux(irr::SIrrlichtCreationParameters const&) (in /home/foo/development/workspace/AnimatorTutorial/Release/AnimatorTutorial)
==4129==    by 0x804FBC9: createDeviceEx (in /home/foo/development/workspace/AnimatorTutorial/Release/AnimatorTutorial)
==4129==    by 0x804EF24: main (main.cpp:14)
==4129== 
==4129== 
==4129== 17,096 bytes in 148 blocks are definitely lost in loss record 35 of 35
==4129==    at 0x4020E22: calloc (vg_replace_malloc.c:397)
==4129==    by 0x48F55B4: ???
==4129==    by 0x48981DC: ???
==4129==    by 0x488FAA9: ???
==4129==    by 0x488B3C0: ???
==4129==    by 0x404DEB3: (within /usr/lib/libGL.so.1.2)
==4129==    by 0x404E31D: glXCreateContext (in /usr/lib/libGL.so.1.2)
==4129==    by 0x8052C97: irr::CIrrDeviceLinux::createWindow() (in /home/foo/development/workspace/AnimatorTutorial/Release/AnimatorTutorial)
==4129==    by 0x8057BA6: irr::CIrrDeviceLinux::CIrrDeviceLinux(irr::SIrrlichtCreationParameters const&) (in /home/foo/development/workspace/AnimatorTutorial/Release/AnimatorTutorial)
==4129==    by 0x804FBC9: createDeviceEx (in /home/foo/development/workspace/AnimatorTutorial/Release/AnimatorTutorial)
==4129==    by 0x804EF24: main (main.cpp:14)
==4129== 
==4129== LEAK SUMMARY:
==4129==    definitely lost: 17,600 bytes in 158 blocks.
==4129==    indirectly lost: 1,628 bytes in 11 blocks.
==4129==      possibly lost: 0 bytes in 0 blocks.
==4129==    still reachable: 23,766 bytes in 316 blocks.
==4129==         suppressed: 0 bytes in 0 blocks.
PS:

Code: Select all

for (int j=0;j<500;j++)
A leak is a leak. No need run the loop 500 times. :)
"Whoops..."
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

Yeah, I fear that if there is a problem with VBOs in the code shown, then it's Windows only. The cleanup of the devices differs, and also the implementations in the drivers. Also, most of the mem leaks shown in valgrind are due to the OpenGL hw drivers, and some are from X11. In most cases we cannot do anything there, although I never got the ones from GLContext on my machines. Would be interesting to check if those are for real.
bonsalty
Posts: 120
Joined: Thu Dec 10, 2009 1:30 pm
Location: Budapest,Hungary

Post by bonsalty »

Actually its growing with megabytes. I tried with the loader instead of eliminating the node and creating a new one,but its the same. In the original code, I have to refresh the surface(always changing) thats why it should work with a loop. Do you have any other idea? We covered earlier this problem.
driver->removeHardwareBuffer(terrain->getRenderBuffer());
should be called before each terrain->loadHeightMap?
In Win7 this seems to have no effect.
Tomi
bonsalty
Posts: 120
Joined: Thu Dec 10, 2009 1:30 pm
Location: Budapest,Hungary

Post by bonsalty »

This is the altered version. The node is not removed, but the heights are constantly changed.

Code: Select all

int main()
{
	// ask user for driver
	video::E_DRIVER_TYPE driverType=video::EDT_DIRECT3D9;
	if (driverType==video::EDT_COUNT)
		return 1;

	irr::SIrrlichtCreationParameters params;
	params.DriverType=driverType;
	params.WindowSize=core::dimension2d<u32>(640, 480);
	IrrlichtDevice* device = createDeviceEx(params);

	if (device == 0)return 1; // could not create selected driver.

	
	video::IVideoDriver* driver = device->getVideoDriver();
	scene::ISceneManager* smgr = device->getSceneManager();
	gui::IGUIEnvironment* env = device->getGUIEnvironment();

	
	scene::ICameraSceneNode* camera =	smgr->addCameraSceneNode(0,core::vector3df(0,1700.0f,0),core::vector3df(1010,0.0f,1100));

	
	char* lpBits = (char*)malloc(129*129*sizeof(char));
 
    scene::ITerrainSceneNode* terrain = smgr->addTerrainSceneNode(   // Adding node 
      NULL,   
      0,               // parent node
      -1,               // node id
      core::vector3df(0.f, 0.f, 0.f),      // position
      core::vector3df(0.f, 0.f, 0.f),      // rotation
      core::vector3df(40.f, 4.4f, 40.f),   // scale
      video::SColor ( 0, 0, 0, 255 ),   // vertexColor
      5,              // maxLOD
      scene::ETPS_17,            // patchSize
      4,               // smoothFactor
      true
      );       

	io::IReadFile* file = NULL;
   //...............................................................
	for (int j=1;j<500;j++){
	
		for(u32 t = 0; t < 129*129; ++t){ 
			lpBits[t] = rand() % 20 + rand() % j; // loading heights
		}
	file=device->getFileSystem()->createMemoryReadFile(&lpBits, 129*129* sizeof(char), "heightmap",false);
	//file->seek(0);
    
	terrain->loadHeightMapRAW(file,8); 
	
	file->drop();
	terrain->setMaterialTexture(0,driver->getTexture("../../media/terrain-texture.jpg"));
	terrain->setMaterialType(video::EMT_LIGHTMAP);

	driver->beginScene();
	smgr->drawAll();
	env->drawAll();
	driver->endScene();
	
	driver->removeHardwareBuffer(terrain->getRenderBuffer()); 
	
	
	
	} // end for j

	delete lpBits;	
	device->drop();
	
	return 0;
}


0->300 megabytes in 5 sec
:cry:
Tomi
Alastriona
Posts: 23
Joined: Sat Apr 17, 2010 3:36 pm

Post by Alastriona »

EDIT: nevermind I'm used to Allman style indentation. Damn you K&R!!!
Last edited by Alastriona on Mon Apr 19, 2010 12:55 pm, edited 3 times in total.
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

The j loop is larger than only this value setting. So the array is changed and then rendered.
bonsalty: First of all, it won't help if you keep on posting almost the same code all the time. You have to debug the situation and find the cause of this problem. As you have seen from the other posts it's not a general problem. And as I said it only affects Direct3D, so changing to OpenGL should also help (at least as a temporary fix).
Moreover, it's basically your fault. The terrain uses a VBO hardware mapping hint of EHM_STATIC. This means that you're not supposed to alter the vertices at all. You should change that to EHM_STREAM, and also call setDirty() after changing the vertices. Also make sure that the terrain loading procedure does not reset the flags.
Post Reply