forked from 0ad/0ad
MICROLOG function for high-speed logging of everything that happened just before a crash
This was SVN commit r761.
This commit is contained in:
parent
af9cf31691
commit
82de48832e
@ -58,6 +58,35 @@ void debug_break()
|
||||
}
|
||||
|
||||
|
||||
wchar_t MicroBuffer[MICROLOG_SIZE];
|
||||
int MicroBuffer_off = 0;
|
||||
|
||||
void debug_microlog(const wchar_t *fmt, ...)
|
||||
{
|
||||
va_list argp;
|
||||
wchar_t buffer[512];
|
||||
int count = 0;
|
||||
|
||||
va_start(argp, fmt);
|
||||
vsnwprintf(buffer, sizeof(buffer), fmt, argp);
|
||||
va_end(argp);
|
||||
|
||||
wcscat(buffer, L"\r\n");
|
||||
|
||||
int len = (int)wcslen(buffer);
|
||||
|
||||
// Lose half of the old data if the log's too big
|
||||
if (MicroBuffer_off + len >= MICROLOG_SIZE)
|
||||
{
|
||||
memcpy(&MicroBuffer, (void*)&MicroBuffer[MICROLOG_SIZE/2], sizeof(wchar_t)*MICROLOG_SIZE/2);
|
||||
memset(&MicroBuffer[MICROLOG_SIZE/2], 0, sizeof(wchar_t)*MICROLOG_SIZE/2);
|
||||
MicroBuffer_off -= MICROLOG_SIZE/2;
|
||||
}
|
||||
memcpy(&MicroBuffer[MicroBuffer_off], buffer, sizeof(wchar_t)*len);
|
||||
MicroBuffer_off += len;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
||||
|
@ -37,6 +37,13 @@ extern int debug_assert_failed(const char* source_file, int line, const char* ex
|
||||
extern int debug_write_crashlog(const char* file, wchar_t* header, void* context);
|
||||
|
||||
|
||||
// Small fast(ish) log for recording the events leading up to a crash:
|
||||
#define MICROLOG debug_microlog
|
||||
//#define MICROLOG (void)
|
||||
|
||||
const int MICROLOG_SIZE = 16384;
|
||||
void debug_microlog(const wchar_t *fmt, ...);
|
||||
|
||||
extern void check_heap();
|
||||
|
||||
|
||||
|
@ -30,7 +30,6 @@
|
||||
#include "wdbg.h"
|
||||
#include "assert_dlg.h"
|
||||
|
||||
|
||||
/*
|
||||
* voodoo programming. PDB debug info is a poorly documented mess.
|
||||
* see http://msdn.microsoft.com/msdnmag/issues/02/03/hood/default.aspx
|
||||
@ -784,10 +783,9 @@ static void DumpMiniDump(HANDLE hFile, PEXCEPTION_POINTERS excpInfo)
|
||||
// }
|
||||
}
|
||||
|
||||
const int MICROLOG_SIZE = 16384;
|
||||
int MicroBuffer_size = MICROLOG_SIZE;
|
||||
wchar_t MicroBuffer[MICROLOG_SIZE];
|
||||
int MicroBuffer_off = 0;
|
||||
// From sysdep.h
|
||||
extern wchar_t MicroBuffer[];
|
||||
extern int MicroBuffer_off;
|
||||
|
||||
int debug_write_crashlog(const char* file, wchar_t* header, void* context)
|
||||
{
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "Renderer.h"
|
||||
#include "PatchRData.h"
|
||||
#include "AlphaMapCalculator.h"
|
||||
#include "ps/CLogger.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
// shared list of all submitted patches this frame
|
||||
@ -543,6 +544,7 @@ void CPatchRData::RenderBaseSplats()
|
||||
uint i;
|
||||
|
||||
// set up texture environment for base pass
|
||||
MICROLOG(L"base splat textures");
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
|
||||
@ -557,12 +559,15 @@ void CPatchRData::RenderBaseSplats()
|
||||
|
||||
#if 1
|
||||
// submit base batches for each patch to the vertex buffer
|
||||
MICROLOG(L"submitting %d patches", m_Patches.size());
|
||||
for (i=0;i<m_Patches.size();++i) {
|
||||
MICROLOG(L"%d", i);
|
||||
CPatchRData* patchdata=(CPatchRData*) m_Patches[i]->GetRenderData();
|
||||
patchdata->SubmitBaseBatches();
|
||||
}
|
||||
|
||||
// render base passes for each patch
|
||||
MICROLOG(L"get buffer list");
|
||||
const std::list<CVertexBuffer*>& buffers=g_VBMan.GetBufferList();
|
||||
std::list<CVertexBuffer*>::const_iterator iter;
|
||||
for (iter=buffers.begin();iter!=buffers.end();++iter) {
|
||||
@ -575,16 +580,20 @@ void CPatchRData::RenderBaseSplats()
|
||||
|
||||
// setup data pointers
|
||||
u32 stride=sizeof(SBaseVertex);
|
||||
MICROLOG(L"data pointers");
|
||||
glVertexPointer(3,GL_FLOAT,stride,base+offsetof(SBaseVertex,m_Position));
|
||||
glColorPointer(4,GL_UNSIGNED_BYTE,stride,base+offsetof(SBaseVertex,m_Color));
|
||||
glTexCoordPointer(2,GL_FLOAT,stride,base+offsetof(SBaseVertex,m_UVs[0]));
|
||||
|
||||
// render each batch
|
||||
MICROLOG(L"render batches");
|
||||
for (i=0;i<batches.size();++i) {
|
||||
MICROLOG(L"b");
|
||||
const CVertexBuffer::Batch* batch=batches[i];
|
||||
if (batch->m_IndexData.size()>0) {
|
||||
g_Renderer.BindTexture(0,tex_id(batch->m_Texture));
|
||||
for (uint j=0;j<batch->m_IndexData.size();j++) {
|
||||
MICROLOG(L"e");
|
||||
glDrawElements(GL_QUADS,(GLsizei)batch->m_IndexData[j].first,GL_UNSIGNED_SHORT,batch->m_IndexData[j].second);
|
||||
g_Renderer.m_Stats.m_DrawCalls++;
|
||||
g_Renderer.m_Stats.m_TerrainTris+=(u32)batch->m_IndexData[j].first/2;
|
||||
@ -594,6 +603,7 @@ void CPatchRData::RenderBaseSplats()
|
||||
}
|
||||
}
|
||||
// everything rendered; empty out batch lists
|
||||
MICROLOG(L"clear");
|
||||
g_VBMan.ClearBatchIndices();
|
||||
#else
|
||||
for (i=0;i<m_Patches.size();++i) {
|
||||
|
@ -721,14 +721,17 @@ void CRenderer::RenderPatches()
|
||||
{
|
||||
// switch on wireframe if we need it
|
||||
if (m_TerrainRenderMode==WIREFRAME) {
|
||||
MICROLOG(L"wireframe on");
|
||||
glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
|
||||
}
|
||||
|
||||
// render all the patches, including blend pass
|
||||
MICROLOG(L"render patch submissions");
|
||||
RenderPatchSubmissions();
|
||||
|
||||
if (m_TerrainRenderMode==WIREFRAME) {
|
||||
// switch wireframe off again
|
||||
MICROLOG(L"wireframe off");
|
||||
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
|
||||
} else if (m_TerrainRenderMode==EDGED_FACES) {
|
||||
/*
|
||||
@ -876,23 +879,35 @@ void CRenderer::FlushFrame()
|
||||
// std::sort(m_Models.begin(),m_Models.end(),SortModelsByTexture());
|
||||
|
||||
// sort all the transparent stuff
|
||||
MICROLOG(L"sorting");
|
||||
g_TransparencyRenderer.Sort();
|
||||
if (!m_ShadowRendered) {
|
||||
if (m_Options.m_Shadows) RenderShadowMap();
|
||||
if (m_Options.m_Shadows) {
|
||||
MICROLOG(L"render shadows");
|
||||
RenderShadowMap();
|
||||
}
|
||||
// clear buffers
|
||||
MICROLOG(L"clear buffer");
|
||||
glClearColor(m_ClearColor[0],m_ClearColor[1],m_ClearColor[2],m_ClearColor[3]);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
}
|
||||
|
||||
// render submitted patches and models
|
||||
MICROLOG(L"render patches");
|
||||
RenderPatches();
|
||||
MICROLOG(L"render models");
|
||||
RenderModels();
|
||||
if (m_Options.m_Shadows && !m_ShadowRendered) ApplyShadowMap();
|
||||
if (m_Options.m_Shadows && !m_ShadowRendered) {
|
||||
MICROLOG(L"apply shadows");
|
||||
ApplyShadowMap();
|
||||
}
|
||||
m_ShadowRendered=true;
|
||||
// call on the transparency renderer to render all the transparent stuff
|
||||
MICROLOG(L"render transparent");
|
||||
g_TransparencyRenderer.Render();
|
||||
|
||||
// empty lists
|
||||
MICROLOG(L"empty lists");
|
||||
g_TransparencyRenderer.Clear();
|
||||
CPatchRData::ClearSubmissions();
|
||||
CModelRData::ClearSubmissions();
|
||||
@ -961,17 +976,25 @@ void CRenderer::Submit(COverlay* overlay)
|
||||
void CRenderer::RenderPatchSubmissions()
|
||||
{
|
||||
// switch on required client states
|
||||
MICROLOG(L"enable vertex array");
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
MICROLOG(L"enable color array");
|
||||
glEnableClientState(GL_COLOR_ARRAY);
|
||||
MICROLOG(L"enable tex coord array");
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
|
||||
// render everything
|
||||
MICROLOG(L"render base splats");
|
||||
CPatchRData::RenderBaseSplats();
|
||||
MICROLOG(L"render blend splats");
|
||||
CPatchRData::RenderBlendSplats();
|
||||
|
||||
// switch off all client states
|
||||
MICROLOG(L"disable tex coord array");
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
MICROLOG(L"disable color array");
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
MICROLOG(L"disable vertex array");
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <assert.h>
|
||||
#include "ogl.h"
|
||||
#include "VertexBufferManager.h"
|
||||
#include "ps/CLogger.h"
|
||||
|
||||
CVertexBufferManager g_VBMan;
|
||||
|
||||
@ -50,7 +51,11 @@ CVertexBuffer::VBChunk* CVertexBufferManager::Allocate(size_t vertexSize,size_t
|
||||
|
||||
// TODO, RC - assert not really suitable? probably need to handle "failed to create
|
||||
// VBO case" better
|
||||
assert(result);
|
||||
if (!result)
|
||||
{
|
||||
LOG(ERROR, "Failed to create VBOs");
|
||||
assert2(!"Failed to create VBOs");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include "ScriptGlue.h"
|
||||
#include "CConsole.h"
|
||||
#include "CLogger.h"
|
||||
#include "CStr.h"
|
||||
#include "EntityHandles.h"
|
||||
#include "Entity.h"
|
||||
@ -32,6 +33,7 @@ JSFunctionSpec ScriptFunctionTable[] =
|
||||
{"getGlobal", getGlobal, 0, 0, 0 },
|
||||
{"getGUIGlobal", getGUIGlobal, 0, 0, 0 },
|
||||
{"exit", exitProgram, 0, 0, 0 },
|
||||
{"crash", crash, 0, 0, 0 },
|
||||
{0, 0, 0, 0, 0},
|
||||
};
|
||||
|
||||
@ -145,3 +147,10 @@ JSBool exitProgram(JSContext* context, JSObject* globalObject, unsigned int argc
|
||||
kill_mainloop();
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JSBool crash(JSContext* context, JSObject* globalObject, unsigned int argc, jsval* argv, jsval* rval)
|
||||
{
|
||||
MICROLOG(L"Crashing.");
|
||||
uintptr_t ptr = 0xDEADC0DE;
|
||||
return *(JSBool*) ptr;
|
||||
}
|
||||
|
@ -21,6 +21,9 @@ JSBool getGlobal(JSContext* context, JSObject* globalObject, unsigned int argc,
|
||||
// Tells the main loop to stop looping
|
||||
JSBool exitProgram(JSContext* context, JSObject* globalObject, unsigned int argc, jsval* argv, jsval* rval);
|
||||
|
||||
// Crashes.
|
||||
JSBool crash(JSContext* context, JSObject* globalObject, unsigned int argc, jsval* argv, jsval* rval);
|
||||
|
||||
extern JSFunctionSpec ScriptFunctionTable[];
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user