Heap Corruption?

Programmiersprachen, APIs, Bibliotheken, Open Source Engines, Debugging, Quellcode Fehler und alles was mit praktischer Programmierung zu tun hat.
Antworten
Andre
Establishment
Beiträge: 186
Registriert: 21.12.2011, 20:33

Heap Corruption?

Beitrag von Andre »

Guten Abend an alle ZFXler.

Vor ein paar Tagen dachte ich noch "Mensch, baust du doch mal eben diese PostProcess-GodRays ein. Das sollte schnell gehen". Tja. Das funktioniert nun auch und sieht auch toll aus und alles. Aber leider nur unter bestimmten Umständen. Im Debugmodus ist alles okay. Egal ob der Debugger dranhängt oder nicht.
Im Releasemodus klappt es nur solange der Debugger von Anfang an am Programm ist. Andernfalls brach das ganze beim Laden eines Levels mit DirectionalLight in einem Aufruf von newab, und mir wurde der Fehlercode "c0000374" in den Debugoutput geschrieben. Laut Google ist also etwas mit meinem Heap nicht in Ordnung. Ich fand sogar einen alten Thread auf Gamedev.Net in dem ich das selbe Problem hatte, es aber nie gelöst bekam (Handelte sich nur um ein kleines Test-Programm). Dass das ganze nur im Releasemodus ohne Debugger abstürzt bekräftigt weiter meine Vermutung, dass es eine Heap Corruption ist, da eben nicht der Debug-Heap benutzt wird.

Full Page Heap sollte ich stattdessen anstellen, habe ich gelesen. Außerdem mit /MD statt /MDd kompilieren. Das solle helfen den Fehler zu finden. Nungut. Nun crasht es woanders mit einer Access Violation beim Schreiben. Einzelheiten dazu später.

Das komische an dem Ganzen ist, finde ich, dass das alles nur passiert wenn ich eine Membervariable zu der Klasse hinzufüge. Das viel mir auf als ich verzweifelt anfing Code auszukommentieren. Ich kommentierte also einige Pointer, die schon gar nicht mehr im Code benutzt wurden, da alles wegkommentiert war, aus, und schon klappte wieder alles. Aus Jux habe ich dann einfach mal ein paar Ints dazugeschrieben und auch das bewirkte einen Crash.

Leider passieren die Crashes nicht immer an der selben Stelle. Eben hatte ich die Situation, dass die erste Zuweisung nach dem Konstruktor das ganze zum Abstürzen brachte. Hatte schon gehofft, dass vielleicht irgendwas das Objekt dazwischen löscht. Jetzt crasht es leider noch bevor die erste Zeile meines Codes im Konstruktor aufgerufen wird.

Davon hab ich einfach mal einen Screenshot gemacht:
heapcrash.png
Wäre es möglich, dass ein anderes Objekt da einfach über seine Grenzen gelöscht wird, etwas überschreibt oder sonstirgendwas, was es nicht soll, und das alles daher kommt?
Bevor ich die GodRays eingebaut habe hatten wir solche Probleme nicht. Und ich habe auch leider keine Ahnung mehr wie ich das noch Debuggen soll.
Ihr seid also sozusagen die letzte Hoffnung für die Godrays in unserer Engine dabeizusein... :roll:
Benutzeravatar
Artificial Mind
Establishment
Beiträge: 802
Registriert: 17.12.2007, 17:51
Wohnort: Aachen

Re: Heap Corruption?

Beitrag von Artificial Mind »

1. Ich hoffe einfach, dass ihr ein Versionskontrollsystem benutzt: Diff'en und Versionen auschecken, bis der schuldige Code gefunden ist
2. Valgrind nutzen, um uninitialized memory zu finden
3. Valgrind nutzen, um out-of-bound Zugriffe zu finden
4. Den delete Operator der betroffenen Klassen so überladen, dass man mitbekommt, wenn das gleiche Objekt mehrmals gelöscht wird. (Ich hoffe das geht so, wie ich mir das vorstelle. Also quasi einen bool deleted (init auf false) in die Klasse einbauen und anstatt die Klasse zu löschen bei delete einfach den bool auf true setzen. Wenn der bool allerdings schon true war, wurde etwas doppelt gelöscht.)
Andre
Establishment
Beiträge: 186
Registriert: 21.12.2011, 20:33

Re: Heap Corruption?

Beitrag von Andre »

1. Ich hoffe einfach, dass ihr ein Versionskontrollsystem benutzt: Diff'en und Versionen auschecken, bis der schuldige Code gefunden ist
Da ich da alleine dran Programmiere haben wir soetwas leider nicht. Wäre allerdings bald mal an der Zeit wenn ich mir das ganze so anschaue. :(
Die Änderungen an sich sind allerdings recht überschaubar.
2. Valgrind nutzen, um uninitialized memory zu finden
3. Valgrind nutzen, um out-of-bound Zugriffe zu finden
Bin leider auf Windows beschränkt. Habe mich schon damals geärgert, dass es das nur für Linux gibt. Gibt es da vielleicht Alternativen?
Ich lese immer wieder was von PageHeap, welches in den Microsoft Debugging Tools enthalten ist. Ich habe es auch aktiviert. Der Sinn des Tools ist wohl, dass es Buffer Overruns oder Underruns abfängt und dort Crasht. Das Tool war übrigens aktiviert als ich den Screenshot da oben gemacht habe.
4. Den delete Operator der betroffenen Klassen so überladen, dass man mitbekommt, wenn das gleiche Objekt mehrmals gelöscht wird. (Ich hoffe das geht so, wie ich mir das vorstelle. Also quasi einen bool deleted (init auf false) in die Klasse einbauen und anstatt die Klasse zu löschen bei delete einfach den bool auf true setzen. Wenn der bool allerdings schon true war, wurde etwas doppelt gelöscht.)
Wo kann sich denn noch ein delete verstecken wenn es mir im Konstruktor schon abschmiert? Naja, das kann wegen PageHeap sein. Ich werde das mal wieder deaktivieren und deine Idee probieren.
j.klugmann
Establishment
Beiträge: 201
Registriert: 07.07.2010, 13:00
Kontaktdaten:

Re: Heap Corruption?

Beitrag von j.klugmann »

Versionsverwaltungssysteme wie Git oder SVN sind auch tierrisch nützlich, wenn man alleine entwickelt.

Ansonsten lösche per Hand alle Object-Files und versuche mal komplett neu zu kompilieren.
Imaging-Software und bald auch Middleware: http://fd-imaging.com
j.klugmann
Establishment
Beiträge: 201
Registriert: 07.07.2010, 13:00
Kontaktdaten:

Re: Heap Corruption?

Beitrag von j.klugmann »

Ansonsten solltest du vielleicht mal etwas Source zeigen...
Imaging-Software und bald auch Middleware: http://fd-imaging.com
Andre
Establishment
Beiträge: 186
Registriert: 21.12.2011, 20:33

Re: Heap Corruption?

Beitrag von Andre »

j.klugmann hat geschrieben:Ansonsten lösche per Hand alle Object-Files und versuche mal komplett neu zu kompilieren.
Wird nach Artificial Mind's Vorschlag gemacht. Egentlich hatte ich aber nach dem ändern der Runtime-DLL einen Full-Build hinter mir. Vielleicht hilft's ja trotzdem.
j.klugmann hat geschrieben:Ansonsten solltest du vielleicht mal etwas Source zeigen...
Gerne, ich frage mich nur von was genau?

Hier ist mein Licht (Vorsicht, musste mehrere Tage wütendes herrumfrikeln über sich ergehen lassen!):

Code: Alles auswählen

#pragma once
#include "DXUT.h"
#include "WBaseLightComponent.h"
#include "ScreenQuadHelper.h"


class EditorLinePrimitive;
class WShader;
class SceneRenderer_ToDepthBuffer;
class WDirectionalLightComponent:public WBaseLightComponent
{
public:
	WDirectionalLightComponent();
    ~WDirectionalLightComponent();

	/** Basic component functions */
	virtual void OnCreate();
	virtual void RenderComponent(int NumInst,bool bSelected=false);
	virtual void PreRenderContentMark();

	/** Called when the shadowmapping property has changed */
	void UseShadowmapPropertyChanged();

	/** Sets the pointer to the property container */
	virtual void SetPropertyContainer(wpsPropertyContainer* NewContainer);
private:

	/** Info primitive */
	EditorLinePrimitive* InfoPrimitive;

	/** Shadow map renderer */
	SceneRenderer_ToDepthBuffer* ShadowMapRenderer;
	SceneRenderer_ToDepthBuffer* ShadowMapRenderer2;
	SceneRenderer_ToDepthBuffer* ShadowMapRenderer3;

	/** Properties */
	
	wColorProperty* IndirectLightingColorProperty;
	wBoolProperty* UseShadowmappingProperty;
	wFloatProperty* CascadeScaleProperty;

/////////// Neue Properties, die ich für die GodRays eingefügt hatte. Nach dem Auskommentieren gabs keine Crashes mehr /////////// 
	/*wBoolProperty* bRenderGodRaysProperty; 
	wFloatProperty* GodRayDensityProperty;
	wFloatProperty* GodRayWeightProperty;
	wFloatProperty* GodRayDecayProperty;
	wColorProperty* GodRayColorModProperty;
	wFloatProperty* GodRayMinimumBrightnessProperty;*/
	int Test1;  // <----- Hier sind meine Test-Ints. Manchmal (immer?) reicht auch schon eines davon um die Sache abstürzen zu lassen.
	int Test2;
	int Test3;
	int Test4;
	int Test5;
	int Test6;


	/** Shader custom variables */
	int LightDirectionIndex;
	int NormalTexIndex;
	int DepthTexIndex;
	int IndirLightingColorIndex;
	int ProjABIndex;
	int invProjIndex;
	int LightViewProjMatrixIndex;
	int LightViewProjMatrix2Index;
	int LightViewProjMatrix3Index;
	int invViewMatrixIndex;
	int ShadowMap1Index;
	int ShadowMap2Index;
	int ShadowMap3Index;


	/** Screenquad-Mesh */
	ScreenQuadHelper ScreenQuad;

	/** Shader for pointlight */
	WShader* LightShader;
};
Konstruktor + Init-Funktion:

Code: Alles auswählen

#include "DXUT.h"
#include "WDirectionalLightComponent.h"
#include "EditorLinePrimitive.h"
#include "SceneRenderer_ToDepthBuffer.h"
#include "WCamera.h"
#include "WContentMark.h"
#include "SharedParameters.h"
#include "WTechPackage2.h"
#include "WPckFileChunk.h"
#include "PackageHandler.h"
#include "AllClasses.h"
#include "PostFX_GodRays.h"


WDirectionalLightComponent::WDirectionalLightComponent()
{
	bDeleted = false;

	MyClass=WDIRECTIONALLIGHTCOMPONENT;
	bLetMeDoTheRenderGroupCheck = true;

	ShadowMapRenderer=NULL;
	ShadowMapRenderer2=NULL;
	ShadowMapRenderer3=NULL;

	IndirectLightingColorProperty = Properties->CreateColor("Indirect Lightcolor");
	IndirectLightingColorProperty->Set(&D3DXVECTOR4(0.5, 0.5, 0.5, 0));
	UseShadowmappingProperty = Properties->CreateBool("Shadows");
	UseShadowmappingProperty->Set(false);

	CascadeScaleProperty = Properties->CreateFloat("Cascade Scale");
	CascadeScaleProperty->Set(1.0f);


	/*bRenderGodRaysProperty = Properties->CreateBool("Render GodRays");
	bRenderGodRaysProperty->Set(false);

	GodRayDensityProperty = Properties->CreateFloat("GodRays Density");
	GodRayDensityProperty->Set(0.5);

	GodRayWeightProperty = Properties->CreateFloat("GodRays Weight");
	GodRayWeightProperty->Set(0.6);

	GodRayDecayProperty = Properties->CreateFloat("GodRays Decay");
	GodRayDecayProperty->Set(0.9);

	GodRayMinimumBrightnessProperty = Properties->CreateFloat("GodRays Minimum Brightness");
	GodRayMinimumBrightnessProperty->Set(0.7);

	GodRayColorModProperty = Properties->CreateColor("GodRays Color");
	GodRayColorModProperty->Set(&D3DXVECTOR4(1,1,1,1));*/

	InfoPrimitive = new EditorLinePrimitive;
}

/////////// Optimierungen natürlich nur aus damit ich hier ordentlich debuggen kann /////////// 
#pragma optimize( "", off )
void WDirectionalLightComponent::OnCreate()
{
	WBaseLightComponent::OnCreate();

	HRESULT hr;

	// Find light shader in media package
	WTechPackage2* MediaPack;
	SharedParams->PckHandler->FindPackageByName(L"EngineMedia.wpk", &MediaPack);
	LightShader=(WShader *)MediaPack->GetChunkByName(L"DirectionalLightShader.wfx")->GetOwnedObject();
	

	ScreenQuad.CreateQuad();
	ScreenQuad.SetShader(LightShader);

	LightShader->AddCustomVariable("LightDirection",CVT_VECTOR,&LightDirectionIndex);
	LightShader->AddCustomVariable("NormalTex",CVT_SHADER_RES_VIEW,&NormalTexIndex);
	LightShader->AddCustomVariable("IndirectLightColor",CVT_VECTOR,&IndirLightingColorIndex);
	LightShader->AddCustomVariable("DepthTex",CVT_SHADER_RES_VIEW,&DepthTexIndex);
	LightShader->AddCustomVariable("ProjAB",CVT_VECTOR,&ProjABIndex);
	LightShader->AddCustomVariable("invProj",CVT_VECTOR,&invProjIndex);
	
	LightShader->AddCustomVariable("invView",CVT_MATRIX,&invViewMatrixIndex);

	
	LightShader->AddCustomVariable("LightViewProjMatrix",CVT_MATRIX,&LightViewProjMatrixIndex);
	LightShader->AddCustomVariable("LightViewProjMatrix2",CVT_MATRIX,&LightViewProjMatrix2Index);
	LightShader->AddCustomVariable("LightViewProjMatrix3",CVT_MATRIX,&LightViewProjMatrix3Index);

	LightShader->AddCustomVariable("ShadowMap1",CVT_SHADER_RES_VIEW,&ShadowMap1Index);
	LightShader->AddCustomVariable("ShadowMap2",CVT_SHADER_RES_VIEW,&ShadowMap2Index);
	LightShader->AddCustomVariable("ShadowMap3",CVT_SHADER_RES_VIEW,&ShadowMap3Index);

	// Init our Line-Primitive
	InfoPrimitive->CreateArrowPrimitive(&WBASELIGHTCOMPONENT_LINE_COLOR);
	InfoPrimitive->SetShader((WShader *)MediaPack->GetChunkByName(L"ColoredLinePrimitiveShader.wfx")->GetOwnedObject());
}
#pragma optimize( "", on )
Erstellung des Objektes:

Code: Alles auswählen

WObject* WPckFileChunk::CreateOwnedObject(WClass ObjectClass,int Index,bool bContentMarkTarget)
{
	if(Index<MaxOwnedObjects)
	{

// CreateObjByClass() beinhaltet nur ein großes, generiertes, switch-statement in dem für das hier dieser code ausgeführt wird:
// case WDIRECTIONALLIGHTCOMPONENT:
// *Out=new WDirectionalLightComponent;
// return true;
		CreateObjByClass(ObjectClass,(void **)&OwnedObject[Index]); 

		if(OwnedObject[Index])
		{
			//OnCreatedContentObject(OwnedObject[Index],false);
			Box->RegisterObject(OwnedObject[Index]);
			OwnedObject[Index]->SetMyFileChunk(this);
		}
		ContentMarkTargetObject=Index;
		return OwnedObject[Index];
	}else
	{
		LogError() << L"Failed to create owned object. Index exceeds" << MaxOwnedObjects-1;
		return NULL;
	}
}
Edit: Ohne PageHeap crasht es hier:

Code: Alles auswählen

/** Creates the buffers and sets up the rest of the object */
HRESULT EditorLinePrimitive::CreatePrimitive(VertexStruct* PrimVerts, UINT NumVertices, D3D11_PRIMITIVE_TOPOLOGY Topology)
{
	HRESULT hr=S_OK;

	// Clean up previous data
	DeleteContent();

	// Copy over the new data
	Vertices = new VertexStruct[NumVertices]; // <------ Crash hier, bei "_heap_alloc"
	memcpy(Vertices, PrimVerts, sizeof(VertexStruct)*NumVertices);
	this->NumVertices = NumVertices;
	
	//Create the vertex buffer
	D3D11_BUFFER_DESC bufferDesc;
    bufferDesc.ByteWidth = NumVertices * sizeof(VertexStruct);
    bufferDesc.Usage = D3D11_USAGE_DEFAULT;
    bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
    bufferDesc.CPUAccessFlags = 0;
    bufferDesc.MiscFlags = 0;

	D3D11_SUBRESOURCE_DATA InitData;
    InitData.pSysMem = &Vertices[0];
	InitData.SysMemPitch = 0;
	InitData.SysMemSlicePitch = 0;

	LE(DXUTGetD3D11Device()->CreateBuffer(&bufferDesc,&InitData,&PrimVB));

	PrimitiveTopology = Topology;

	return hr;
}



/** Creates an arrow of lines */
HRESULT EditorLinePrimitive::CreateArrowPrimitive(const D3DXVECTOR4* Color,float ArrowRadius, float ArrowOffset)
{
	VertexStruct vx[10];

	

	// Middle streak
	vx[0].Position = D3DXVECTOR3(0, 0, 0);
	vx[1].Position = D3DXVECTOR3(1, 0, 0);

	// Outer lines
	vx[2].Position = D3DXVECTOR3(1, 0, 0);
	vx[3].Position = D3DXVECTOR3(ArrowOffset, ArrowRadius, ArrowRadius);

	vx[4].Position = D3DXVECTOR3(1, 0, 0);
	vx[5].Position = D3DXVECTOR3(ArrowOffset, ArrowRadius, -ArrowRadius);

	vx[6].Position = D3DXVECTOR3(1, 0, 0);
	vx[7].Position = D3DXVECTOR3(ArrowOffset, -ArrowRadius, ArrowRadius);

	vx[8].Position = D3DXVECTOR3(1, 0, 0);
	vx[9].Position = D3DXVECTOR3(ArrowOffset, -ArrowRadius, -ArrowRadius);

	for(int i=0; i< 10; i++)
	{
		EncodeColor(&vx[i], Color);
	}
	HRESULT hr = CreatePrimitive(vx, 10);
	return hr;
}
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: Heap Corruption?

Beitrag von CodingCat »

DeleteContent(); ist auf jeden Fall ein verdächtiger Aufruf in einer Initialisierung. Kandidat für Zugriffsverletzung mit uninitialisierten Variablen?
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: Heap Corruption?

Beitrag von CodingCat »

Bei näherem Hinsehen tippe ich aber auf CreateObjByClass(ObjectClass,(void **)&OwnedObject[Index]);. Derlei void-Casterei ist praktisch nie eine gute Idee, aus folgendem Grund: new gibt dir im switch-Statement einen Zeiger zurück, der auf das vollständig downgecastete Objekt zeigt, der statische Typ stimmt also mit dem dynamischen überein. Konkret hast du beispielsweise einen Zeiger vom Typ WDirectionalLightComponent*. Diesen Zeiger castest du nun zu void*, um ihn auf der anderen Seite wieder zurückzucasten. Das Problem ist, dass du auf der anderen Seite nicht zurück in einen Zeiger des vollen dynamischen Typs, nämlich WDirectionalLightComponent*, castest, sondern stattdessen in einen Zeiger eines Basistyps, hier WObject*. Das kann so praktisch nicht funktionieren, void-Zeiger dürfen im Allgemeinen nur in exakt denselben Zeigertyp zurückgecastet werden, mit dem sie beschrieben wurden. Der Grund dafür ist, dass Vererbung praktisch immer über Subobjekte realisiert ist, was im Fall von Mehrfachvererbung bei Casts eine Adressverschiebung notwendig macht.

Im Speicher beginnt dein Objekt mit dem Subobjekt der obersten Basisklasse, dann folgen alle abgeleiteten Klassen bis zur konkret instantiierten. Bei Einfachvererbung haben einfach alle Subobjekte dieselbe Adresse, weil jedes nachfolgende Subobjekt der Vererbungshierarchie entsprechend auch logisch alle vorangegangenen Subobjekte (entsprechend den Basisklassen) enthält. Beim Arbeiten mit Zeigern eines Basistyps müssen also nur die Daten am Ende deines Gesamtobjekts ignoriert werden, wozu es keiner zusätzlichen Behandlung bedarf.
Anders sieht das bei Mehrfachvererbung aus. Dort gibt es Subobjekte von Basisklassen, die nicht alle vorangegangenen Subobjekte enthalten, weil sich die Vererbungshierarchie nach oben verzweigen kann. In diesem Fall liegt im Speicher erst ein Basiszweig, dann der andere. Um nun sinnvoll mit Zeigern von Klassen eines dieser Basiszweige arbeiten zu können, darf der jeweils andere Zweig in dem Speicher, auf den der jeweilige Zeiger zeigt, nicht vorkommen. Deshalb fügt der Compiler beim Upcast je nach Basiszweig eine Adressverschiebung ein, die die Adresse auf den Anfang des jeweiligen Zweigs setzt. Genau diese Adressverschiebung umgehst du mit deinem void*-Cast.

Damit dein Programm funktioniert, solltest du also dringend void** in WObject** ändern, damit eine derartige Adressverschiebung korrekt direkt nach der Erzeugung der Objekte vorgenommen werden kann. Auf Aufruferseite kannst du sonst mit den unveränderten Zeigern ggf. nicht mehr viel anfangen.
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Andre
Establishment
Beiträge: 186
Registriert: 21.12.2011, 20:33

Re: Heap Corruption?

Beitrag von Andre »

j.klugmann hat geschrieben:Ansonsten lösche per Hand alle Object-Files und versuche mal komplett neu zu kompilieren.
Bild

... ich hätte wissen müssen, dass das am Ende auch noch die Lösung ist. Mein Gott, ich arbeite mit einem Programm von Microsoft. Aus- und wieder Einschalten hat da doch bis jetzt immer geklappt. Ist doch fast das selbe wie recompilen :?

Naja ich danke euch allen für die Mühen. Auch wäre ich wohl ohne den recompile nie nach draußen gegangen um mir die Sternschnuppen anzuschauen.

Und weil es nun also endlich funktioniert gibts von der ganzen Sache auch noch einen Screenshot:
9d6a5e1289d9a9544cb9c9cfebd307849c50809c.jpg
@CodingCat: Auch danke für die Aufklärung was für Tücken im void* noch stecken können. Dass man nichts nach void* casten sollte ist mir bekannt, und ehrlich gesagt weiß ich nicht genau warum ich es dort gemacht habe. Soweit ich mich erinnere ist das so ziemlich die älteste Funktion der ganzen Engine. Die hat sogar als eine der Wenigen den Core-Rewrite den es mal vor einem Jahr ca. gab überstanden.
Werde es auf jeden Fall ändern, mir merken und nie wieder tun :)
Benutzeravatar
Jonathan
Establishment
Beiträge: 2371
Registriert: 04.08.2004, 20:06
Kontaktdaten:

Re: Heap Corruption?

Beitrag von Jonathan »

Das Ergebnis sieht zumindest sehr cool aus :)
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
antisteo
Establishment
Beiträge: 854
Registriert: 15.10.2010, 09:26
Wohnort: Dresdem

Re: Heap Corruption?

Beitrag von antisteo »

Andre hat geschrieben:
1. Ich hoffe einfach, dass ihr ein Versionskontrollsystem benutzt: Diff'en und Versionen auschecken, bis der schuldige Code gefunden ist
Da ich da alleine dran Programmiere haben wir soetwas leider nicht. Wäre allerdings bald mal an der Zeit wenn ich mir das ganze so anschaue. :(
Die Änderungen an sich sind allerdings recht überschaubar.
Schlechteste Ausrede ever. SCNR
http://fedoraproject.org/ <-- freies Betriebssystem
http://launix.de <-- kompetente Firma
In allen Posts ist das imo und das afaik inbegriffen.
Benutzeravatar
Krishty
Establishment
Beiträge: 8245
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Heap Corruption?

Beitrag von Krishty »

Habe ich auf der Arbeit alle zwei Tage, weil VS manchmal die vorkompilierten Header nicht aktualisiert, wenn man ein Attribut hinzufügt. Sobald jemand was an der Datenauslegung einer Klasse geändert hat, geht derjenige rum und sagt allen, dass sie nach dem Abholen der aktuellen Version komplett neu kompilieren sollen.

Privat mache ich sowieso alle zehn Minuten Rebuild All, nur, um mich daran aufzugeilen, dass das in 1,2 s fertig ist :-P
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Andre
Establishment
Beiträge: 186
Registriert: 21.12.2011, 20:33

Re: Heap Corruption?

Beitrag von Andre »

antisteo hat geschrieben:
Andre hat geschrieben:
1. Ich hoffe einfach, dass ihr ein Versionskontrollsystem benutzt: Diff'en und Versionen auschecken, bis der schuldige Code gefunden ist
Da ich da alleine dran Programmiere haben wir soetwas leider nicht. Wäre allerdings bald mal an der Zeit wenn ich mir das ganze so anschaue. :(
Die Änderungen an sich sind allerdings recht überschaubar.
Schlechteste Ausrede ever. SCNR
:roll:
Antworten