Explorar el Código

Detect double freeing resources.

Branimir Karadžić hace 9 años
padre
commit
b9c1deceee
Se han modificado 2 ficheros con 125 adiciones y 75 borrados
  1. 16 16
      src/bgfx.cpp
  2. 109 59
      src/bgfx_p.h

+ 16 - 16
src/bgfx.cpp

@@ -1440,44 +1440,44 @@ namespace bgfx
 
 	void Context::freeAllHandles(Frame* _frame)
 	{
-		for (uint16_t ii = 0, num = _frame->m_numFreeIndexBufferHandles; ii < num; ++ii)
+		for (uint16_t ii = 0, num = _frame->m_freeIndexBuffer.getNumQueued(); ii < num; ++ii)
 		{
-			m_indexBufferHandle.free(_frame->m_freeIndexBufferHandle[ii].idx);
+			m_indexBufferHandle.free(_frame->m_freeIndexBuffer.get(ii).idx);
 		}
 
-		for (uint16_t ii = 0, num = _frame->m_numFreeVertexBufferHandles; ii < num; ++ii)
+		for (uint16_t ii = 0, num = _frame->m_freeVertexBuffer.getNumQueued(); ii < num; ++ii)
 		{
-			destroyVertexBufferInternal(_frame->m_freeVertexBufferHandle[ii]);
+			destroyVertexBufferInternal(_frame->m_freeVertexBuffer.get(ii));
 		}
 
-		for (uint16_t ii = 0, num = _frame->m_numFreeVertexDeclHandles; ii < num; ++ii)
+		for (uint16_t ii = 0, num = _frame->m_freeVertexDecl.getNumQueued(); ii < num; ++ii)
 		{
-			m_vertexDeclHandle.free(_frame->m_freeVertexDeclHandle[ii].idx);
+			m_vertexDeclHandle.free(_frame->m_freeVertexDecl.get(ii).idx);
 		}
 
-		for (uint16_t ii = 0, num = _frame->m_numFreeShaderHandles; ii < num; ++ii)
+		for (uint16_t ii = 0, num = _frame->m_freeShader.getNumQueued(); ii < num; ++ii)
 		{
-			m_shaderHandle.free(_frame->m_freeShaderHandle[ii].idx);
+			m_shaderHandle.free(_frame->m_freeShader.get(ii).idx);
 		}
 
-		for (uint16_t ii = 0, num = _frame->m_numFreeProgramHandles; ii < num; ++ii)
+		for (uint16_t ii = 0, num = _frame->m_freeProgram.getNumQueued(); ii < num; ++ii)
 		{
-			m_programHandle.free(_frame->m_freeProgramHandle[ii].idx);
+			m_programHandle.free(_frame->m_freeProgram.get(ii).idx);
 		}
 
-		for (uint16_t ii = 0, num = _frame->m_numFreeTextureHandles; ii < num; ++ii)
+		for (uint16_t ii = 0, num = _frame->m_freeTexture.getNumQueued(); ii < num; ++ii)
 		{
-			m_textureHandle.free(_frame->m_freeTextureHandle[ii].idx);
+			m_textureHandle.free(_frame->m_freeTexture.get(ii).idx);
 		}
 
-		for (uint16_t ii = 0, num = _frame->m_numFreeFrameBufferHandles; ii < num; ++ii)
+		for (uint16_t ii = 0, num = _frame->m_freeFrameBuffer.getNumQueued(); ii < num; ++ii)
 		{
-			m_frameBufferHandle.free(_frame->m_freeFrameBufferHandle[ii].idx);
+			m_frameBufferHandle.free(_frame->m_freeFrameBuffer.get(ii).idx);
 		}
 
-		for (uint16_t ii = 0, num = _frame->m_numFreeUniformHandles; ii < num; ++ii)
+		for (uint16_t ii = 0, num = _frame->m_freeUniform.getNumQueued(); ii < num; ++ii)
 		{
-			m_uniformHandle.free(_frame->m_freeUniformHandle[ii].idx);
+			m_uniformHandle.free(_frame->m_freeUniform.get(ii).idx);
 		}
 	}
 

+ 109 - 59
src/bgfx_p.h

@@ -1757,64 +1757,56 @@ namespace bgfx
 			m_uniformBuffer->writeUniform(_type, _handle.idx, _value, _num);
 		}
 
-		void free(IndexBufferHandle _handle)
+		bool free(IndexBufferHandle _handle)
 		{
-			m_freeIndexBufferHandle[m_numFreeIndexBufferHandles] = _handle;
-			++m_numFreeIndexBufferHandles;
+			return m_freeIndexBuffer.queue(_handle);
 		}
 
-		void free(VertexDeclHandle _handle)
+		bool free(VertexDeclHandle _handle)
 		{
-			m_freeVertexDeclHandle[m_numFreeVertexDeclHandles] = _handle;
-			++m_numFreeVertexDeclHandles;
+			return m_freeVertexDecl.queue(_handle);
 		}
 
-		void free(VertexBufferHandle _handle)
+		bool free(VertexBufferHandle _handle)
 		{
-			m_freeVertexBufferHandle[m_numFreeVertexBufferHandles] = _handle;
-			++m_numFreeVertexBufferHandles;
+			return m_freeVertexBuffer.queue(_handle);
 		}
 
-		void free(ShaderHandle _handle)
+		bool free(ShaderHandle _handle)
 		{
-			m_freeShaderHandle[m_numFreeShaderHandles] = _handle;
-			++m_numFreeShaderHandles;
+			return m_freeShader.queue(_handle);
 		}
 
-		void free(ProgramHandle _handle)
+		bool free(ProgramHandle _handle)
 		{
-			m_freeProgramHandle[m_numFreeProgramHandles] = _handle;
-			++m_numFreeProgramHandles;
+			return m_freeProgram.queue(_handle);
 		}
 
-		void free(TextureHandle _handle)
+		bool free(TextureHandle _handle)
 		{
-			m_freeTextureHandle[m_numFreeTextureHandles] = _handle;
-			++m_numFreeTextureHandles;
+			return m_freeTexture.queue(_handle);
 		}
 
-		void free(FrameBufferHandle _handle)
+		bool free(FrameBufferHandle _handle)
 		{
-			m_freeFrameBufferHandle[m_numFreeFrameBufferHandles] = _handle;
-			++m_numFreeFrameBufferHandles;
+			return m_freeFrameBuffer.queue(_handle);
 		}
 
-		void free(UniformHandle _handle)
+		bool free(UniformHandle _handle)
 		{
-			m_freeUniformHandle[m_numFreeUniformHandles] = _handle;
-			++m_numFreeUniformHandles;
+			return m_freeUniform.queue(_handle);
 		}
 
 		void resetFreeHandles()
 		{
-			m_numFreeIndexBufferHandles  = 0;
-			m_numFreeVertexDeclHandles   = 0;
-			m_numFreeVertexBufferHandles = 0;
-			m_numFreeShaderHandles       = 0;
-			m_numFreeProgramHandles      = 0;
-			m_numFreeTextureHandles      = 0;
-			m_numFreeFrameBufferHandles  = 0;
-			m_numFreeUniformHandles      = 0;
+			m_freeIndexBuffer.reset();
+			m_freeVertexDecl.reset();
+			m_freeVertexBuffer.reset();
+			m_freeShader.reset();
+			m_freeProgram.reset();
+			m_freeTexture.reset();
+			m_freeFrameBuffer.reset();
+			m_freeUniform.reset();
 		}
 
 		SortKey m_key;
@@ -1864,24 +1856,71 @@ namespace bgfx
 		CommandBuffer m_cmdPre;
 		CommandBuffer m_cmdPost;
 
-		uint16_t m_numFreeIndexBufferHandles;
-		uint16_t m_numFreeVertexDeclHandles;
-		uint16_t m_numFreeVertexBufferHandles;
-		uint16_t m_numFreeShaderHandles;
-		uint16_t m_numFreeProgramHandles;
-		uint16_t m_numFreeTextureHandles;
-		uint16_t m_numFreeFrameBufferHandles;
-		uint16_t m_numFreeUniformHandles;
-		uint16_t m_numFreeWindowHandles;
-
-		IndexBufferHandle m_freeIndexBufferHandle[BGFX_CONFIG_MAX_INDEX_BUFFERS];
-		VertexDeclHandle m_freeVertexDeclHandle[BGFX_CONFIG_MAX_VERTEX_DECLS];
-		VertexBufferHandle m_freeVertexBufferHandle[BGFX_CONFIG_MAX_VERTEX_BUFFERS];
-		ShaderHandle m_freeShaderHandle[BGFX_CONFIG_MAX_SHADERS];
-		ProgramHandle m_freeProgramHandle[BGFX_CONFIG_MAX_PROGRAMS];
-		TextureHandle m_freeTextureHandle[BGFX_CONFIG_MAX_TEXTURES];
-		FrameBufferHandle m_freeFrameBufferHandle[BGFX_CONFIG_MAX_FRAME_BUFFERS];
-		UniformHandle m_freeUniformHandle[BGFX_CONFIG_MAX_UNIFORMS];
+		template<typename Ty, uint32_t Max>
+		struct FreeHandle
+		{
+			FreeHandle()
+				: m_num(0)
+			{
+			}
+
+			bool isQueued(Ty _handle)
+			{
+				for (uint32_t ii = 0, num = m_num; ii < num; ++ii)
+				{
+					if (m_queue[ii].idx == _handle.idx)
+					{
+						return true;
+					}
+				}
+
+				return false;
+			}
+
+			bool queue(Ty _handle)
+			{
+				if (BX_ENABLED(BGFX_CONFIG_DEBUG) )
+				{
+					if (isQueued(_handle) )
+					{
+						return false;
+					}
+				}
+
+				m_queue[m_num] = _handle;
+				++m_num;
+
+				return true;
+			}
+
+			void reset()
+			{
+				m_num = 0;
+			}
+
+			Ty get(uint16_t _idx) const
+			{
+				return m_queue[_idx];
+			}
+
+			uint16_t getNumQueued() const
+			{
+				return m_num;
+			}
+
+			Ty m_queue[Max];
+			uint16_t m_num;
+		};
+
+		FreeHandle<IndexBufferHandle,  BGFX_CONFIG_MAX_INDEX_BUFFERS>  m_freeIndexBuffer;
+		FreeHandle<VertexDeclHandle,   BGFX_CONFIG_MAX_VERTEX_DECLS>   m_freeVertexDecl;
+		FreeHandle<VertexBufferHandle, BGFX_CONFIG_MAX_VERTEX_BUFFERS> m_freeVertexBuffer;
+		FreeHandle<ShaderHandle,       BGFX_CONFIG_MAX_SHADERS>        m_freeShader;
+		FreeHandle<ProgramHandle,      BGFX_CONFIG_MAX_PROGRAMS>       m_freeProgram;
+		FreeHandle<TextureHandle,      BGFX_CONFIG_MAX_TEXTURES>       m_freeTexture;
+		FreeHandle<FrameBufferHandle,  BGFX_CONFIG_MAX_FRAME_BUFFERS>  m_freeFrameBuffer;
+		FreeHandle<UniformHandle,      BGFX_CONFIG_MAX_UNIFORMS>       m_freeUniform;
+
 		TextVideoMem* m_textVideoMem;
 		HMD m_hmd;
 		Stats m_perfStats;
@@ -2184,7 +2223,7 @@ namespace bgfx
 		{
 			BX_WARN(1 <= int32_t(_width)
 				&&  1 <= int32_t(_height)
-				, "Frame buffer resolution width or height cannot be 0 (width %d, height %d)."
+				, "Frame buffer resolution width or height must be larger than 0 (width %d, height %d)."
 				, _width
 				, _height
 				);
@@ -2272,10 +2311,11 @@ namespace bgfx
 		BGFX_API_FUNC(void destroyIndexBuffer(IndexBufferHandle _handle) )
 		{
 			BGFX_CHECK_HANDLE("destroyIndexBuffer", m_indexBufferHandle, _handle);
+			bool ok = m_submit->free(_handle); BX_UNUSED(ok);
+			BX_CHECK(ok, "Index buffer handle %d is already destroyed!", _handle.idx);
 
 			CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::DestroyIndexBuffer);
 			cmdbuf.write(_handle);
-			m_submit->free(_handle);
 		}
 
 		VertexDeclHandle findVertexDecl(const VertexDecl& _decl)
@@ -2319,10 +2359,11 @@ namespace bgfx
 		BGFX_API_FUNC(void destroyVertexBuffer(VertexBufferHandle _handle) )
 		{
 			BGFX_CHECK_HANDLE("destroyVertexBuffer", m_vertexBufferHandle, _handle);
+			bool ok = m_submit->free(_handle); BX_UNUSED(ok);
+			BX_CHECK(ok, "Vertex buffer handle %d is already destroyed!", _handle.idx);
 
 			CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::DestroyVertexBuffer);
 			cmdbuf.write(_handle);
-			m_submit->free(_handle);
 		}
 
 		void destroyVertexBufferInternal(VertexBufferHandle _handle)
@@ -2978,9 +3019,11 @@ namespace bgfx
 			int32_t refs = --sr.m_refCount;
 			if (0 == refs)
 			{
+				bool ok = m_submit->free(_handle); BX_UNUSED(ok);
+				BX_CHECK(ok, "Shader handle %d is already destroyed!", _handle.idx);
+
 				CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::DestroyShader);
 				cmdbuf.write(_handle);
-				m_submit->free(_handle);
 
 				if (0 != sr.m_num)
 				{
@@ -3060,7 +3103,7 @@ namespace bgfx
 		{
 			if (!isValid(_vsh) )
 			{
-				BX_WARN(false, "Vertex/fragment shader is invalid (vsh %d).", _vsh.idx);
+				BX_WARN(false, "Compute shader is invalid (vsh %d).", _vsh.idx);
 				ProgramHandle invalid = BGFX_INVALID_HANDLE;
 				return invalid;
 			}
@@ -3113,9 +3156,11 @@ namespace bgfx
 			int32_t refs = --pr.m_refCount;
 			if (0 == refs)
 			{
+				bool ok = m_submit->free(_handle); BX_UNUSED(ok);
+				BX_CHECK(ok, "Program handle %d is already destroyed!", _handle.idx);
+
 				CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::DestroyProgram);
 				cmdbuf.write(_handle);
-				m_submit->free(_handle);
 
 				shaderDecRef(pr.m_vsh);
 				uint32_t hash = pr.m_vsh.idx;
@@ -3266,9 +3311,11 @@ namespace bgfx
 			int32_t refs = --ref.m_refCount;
 			if (0 == refs)
 			{
+				bool ok = m_submit->free(_handle); BX_UNUSED(ok);
+				BX_CHECK(ok, "Texture handle %d is already destroyed!", _handle.idx);
+
 				CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::DestroyTexture);
 				cmdbuf.write(_handle);
-				m_submit->free(_handle);
 			}
 		}
 
@@ -3398,10 +3445,11 @@ namespace bgfx
 		BGFX_API_FUNC(void destroyFrameBuffer(FrameBufferHandle _handle) )
 		{
 			BGFX_CHECK_HANDLE("destroyFrameBuffer", m_frameBufferHandle, _handle);
+			bool ok = m_submit->free(_handle); BX_UNUSED(ok);
+			BX_CHECK(ok, "Frame buffer handle %d is already destroyed!", _handle.idx);
 
 			CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::DestroyFrameBuffer);
 			cmdbuf.write(_handle);
-			m_submit->free(_handle);
 
 			FrameBufferRef& ref = m_frameBufferRef[_handle.idx];
 			if (!ref.m_window)
@@ -3510,12 +3558,14 @@ namespace bgfx
 
 			if (0 == refs)
 			{
+				bool ok = m_submit->free(_handle); BX_UNUSED(ok);
+				BX_CHECK(ok, "Uniform handle %d is already destroyed!", _handle.idx);
+
 				uniform.m_name.clear();
 				m_uniformHashMap.removeByHandle(_handle.idx);
 
 				CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::DestroyUniform);
 				cmdbuf.write(_handle);
-				m_submit->free(_handle);
 			}
 		}