2025-07-18 08:58 CEST

View Issue Details Jump to Notes ]
IDProjectCategoryView StatusLast Update
0000542Spring engineGeneralpublic2007-05-30 15:22
Reportersemi 
Assigned Totvo 
PrioritynormalSeveritycrashReproducibilityalways
StatusresolvedResolutionfixed 
Product Version 
Target VersionFixed in Version 
Summary0000542: [patch] Ghosted but dead buildings come to LOS : corrupted double-linked list crashes game
DescriptionWhen ghosted but later died buildings come back to LOS, a doubly linked list gets corrupted in rts/Rendering/UnitModels/UnitDrawer.cpp because of line 552 where an iterator to list gB is erased from list ghostBuildings. This results in a crash on both windows and linux, stacktrace pointing to either line 550 or 554 in the mentioned file in 2 observed cases.

My patch fixes this bug, and I've tested it to work.
Steps To ReproduceGo scout enemy buildings that are not jammed, so you get ghosts on the map.
Make sure the buildings die, without you seeing them. Nuke them f.ex.
Go scout the buildings again -> crash.

I am not sure if this happens with both 3do and s3o buildings, or both, but at least one or the other.
Additional InformationThis bug was encountered in a test game with Ashitaka, who found the exact reason for the crash.
TagsNo tags attached.
Checked infolog.txt for Errors
Attached Files
  • diff file icon DrawCloakedUnits_semi.diff (4,285 bytes) 2007-05-30 14:44 -
    Index: rts/Rendering/UnitModels/UnitDrawer.cpp
    ===================================================================
    --- rts/Rendering/UnitModels/UnitDrawer.cpp	(revision 3796)
    +++ rts/Rendering/UnitModels/UnitDrawer.cpp	(working copy)
    @@ -505,70 +505,67 @@
     		}
     	}
     
    -	std::vector<CUnit*> dC;
    -	std::list<GhostBuilding*> gB;
    +	// 3dos
    +	DrawCloakedUnitsHelper(drawCloaked, ghostBuildings, 0);
     
    -	for(int i=0;i<2;++i) {
    -		if(!i) { // 3dos
    -			dC=drawCloaked;
    -			gB=ghostBuildings;
    -		} else { // s3os
    -			dC=drawCloakedS3O;
    -			gB=ghostBuildingsS3O;
    -			SetupForGhostDrawingS3O();
    -			glColor4f(1,1,1,0.3f);
    +	// s3os
    +	SetupForGhostDrawingS3O();
    +	glColor4f(1,1,1,0.3f);
    +	DrawCloakedUnitsHelper(drawCloakedS3O, ghostBuildingsS3O, 1);
    +
    +	// reset gl states
    +	CleanUpGhostDrawing();
    +}
    +
    +void CUnitDrawer::DrawCloakedUnitsHelper(std::vector<CUnit*>& dC, std::list<GhostBuilding*>& gB, int is_s3o)
    +{
    +	// cloaked units and living ghosted buildings
    +	for(vector<CUnit*>::iterator ui=dC.begin();ui!=dC.end();++ui){
    +		if((*ui)->losStatus[gu->myAllyTeam] & LOS_INLOS){
    +			if (is_s3o) {
    +				SetBasicS3OTeamColour((*ui)->team);
    +				texturehandler->SetS3oTexture((*ui)->model->textureType);
    +			}
    +			(*ui)->Draw();
    +		} else {
    +			if((*ui)->losStatus[gu->myAllyTeam] & LOS_CONTRADAR)
    +				glColor4f(0.9f,0.9f,0.9f,0.5f);
    +			else
    +				glColor4f(0.6f,0.6f,0.6f,0.4f);
    +			glPushMatrix();
    +			glTranslatef3((*ui)->pos);
    +			if (is_s3o) {
    +				SetBasicS3OTeamColour((*ui)->team);
    +				texturehandler->SetS3oTexture((*ui)->model->textureType);
    +			}
    +			(*ui)->model->DrawStatic();
    +			glPopMatrix();
     		}
    -		// cloaked units and living ghosted buildings
    -		for(vector<CUnit*>::iterator ui=dC.begin();ui!=dC.end();++ui){
    -			if((*ui)->losStatus[gu->myAllyTeam] & LOS_INLOS){
    -				if(i) {
    -					SetBasicS3OTeamColour((*ui)->team);
    -					texturehandler->SetS3oTexture((*ui)->model->textureType);
    -				}
    -				(*ui)->Draw();
    -			} else {
    -				if((*ui)->losStatus[gu->myAllyTeam] & LOS_CONTRADAR)
    -					glColor4f(0.9f,0.9f,0.9f,0.5f);
    -				else
    -					glColor4f(0.6f,0.6f,0.6f,0.4f);
    +	}
    +
    +	//go through the dead but still ghosted buildings
    +	glColor4f(0.6f,0.6f,0.6f,0.4f);
    +	for(std::list<GhostBuilding*>::iterator gbi=gB.begin();gbi!=gB.end();){
    +		if(loshandler->InLos((*gbi)->pos,gu->myAllyTeam)){
    +			if((*gbi)->decal)
    +				(*gbi)->decal->gbOwner=0;
    +			delete *gbi;
    +			gbi=gB.erase(gbi);
    +		} else {
    +			if(camera->InView((*gbi)->pos,(*gbi)->model->radius*2)){
     				glPushMatrix();
    -				glTranslatef3((*ui)->pos);
    -				if(i) {
    -					SetBasicS3OTeamColour((*ui)->team);
    -					texturehandler->SetS3oTexture((*ui)->model->textureType);
    +				glTranslatef3((*gbi)->pos);
    +				glRotatef((*gbi)->facing*90,0,1,0);
    +				if (is_s3o) {
    +					SetBasicS3OTeamColour((*gbi)->team);
    +					texturehandler->SetS3oTexture((*gbi)->model->textureType);
     				}
    -				(*ui)->model->DrawStatic();
    +				(*gbi)->model->DrawStatic();
     				glPopMatrix();
     			}
    +			++gbi;
     		}
    -
    -		//go through the dead but still ghosted buildings
    -		glColor4f(0.6f,0.6f,0.6f,0.4f);
    -		for(std::list<GhostBuilding*>::iterator gbi=gB.begin();gbi!=gB.end();){
    -			if(loshandler->InLos((*gbi)->pos,gu->myAllyTeam)){
    -				if((*gbi)->decal)
    -					(*gbi)->decal->gbOwner=0;
    -				delete *gbi;
    -				gbi=ghostBuildings.erase(gbi);
    -			} else {
    -				if(camera->InView((*gbi)->pos,(*gbi)->model->radius*2)){
    -					glPushMatrix();
    -					glTranslatef3((*gbi)->pos);
    -					glRotatef((*gbi)->facing*90,0,1,0);
    -					if(i) {
    -						SetBasicS3OTeamColour((*gbi)->team);
    -						texturehandler->SetS3oTexture((*gbi)->model->textureType);
    -					}
    -					(*gbi)->model->DrawStatic();
    -					glPopMatrix();
    -				}
    -				++gbi;
    -			}
    -		}
     	}
    -
    -	// reset gl states
    -	CleanUpGhostDrawing ();
     }
     
     void CUnitDrawer::SetupForUnitDrawing(void)
    Index: rts/Rendering/UnitModels/UnitDrawer.h
    ===================================================================
    --- rts/Rendering/UnitModels/UnitDrawer.h	(revision 3796)
    +++ rts/Rendering/UnitModels/UnitDrawer.h	(working copy)
    @@ -118,6 +118,7 @@
     	void CleanupBasicS3OTexture1(void);
     	void CleanupBasicS3OTexture0(void);
     	void DrawIcon(CUnit * unit, bool asRadarBlip);
    +	void DrawCloakedUnitsHelper(std::vector<CUnit*>& dC, std::list<GhostBuilding*>& gB, int is_s3o);
     };
     
     extern CUnitDrawer* unitDrawer;
    
    diff file icon DrawCloakedUnits_semi.diff (4,285 bytes) 2007-05-30 14:44 +

-Relationships
+Relationships

-Notes

~0000917

tvo (reporter)

Thanks! Committed in r3797
+Notes

-Issue History
Date Modified Username Field Change
2007-05-30 14:44 semi New Issue
2007-05-30 14:44 semi File Added: DrawCloakedUnits_semi.diff
2007-05-30 15:22 tvo Status new => assigned
2007-05-30 15:22 tvo Assigned To => tvo
2007-05-30 15:22 tvo Status assigned => resolved
2007-05-30 15:22 tvo Resolution open => fixed
2007-05-30 15:22 tvo Note Added: 0000917
+Issue History