MICROLOG function for high-speed logging of everything that happened just before a crash

This was SVN commit r761.
This commit is contained in:
Ykkrosh 2004-07-15 19:29:56 +00:00
parent af9cf31691
commit 82de48832e
8 changed files with 92 additions and 8 deletions

View File

@ -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

View File

@ -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();

View File

@ -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)
{

View File

@ -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) {

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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