ogl, h_mgr: tag-ified debug_printf string for use with new filter
debug: filter mechanism now usable. added docs This was SVN commit r3001.
This commit is contained in:
parent
7cb003f18c
commit
d49dd25385
@ -83,13 +83,13 @@ static const int MAX_CHARS = 512;
|
||||
|
||||
|
||||
// rationale: static data instead of std::set to allow setting at any time.
|
||||
// note: need only set the pointer, but strcmp when reading (because
|
||||
// 2 different call sites may have used equal literals at different addresses).
|
||||
// we store FNV hash of tag strings for fast comparison; collisions are
|
||||
// extremely unlikely.
|
||||
static const uint MAX_TAGS = 20;
|
||||
static u32 tags[MAX_TAGS];
|
||||
static uint num_tags;
|
||||
|
||||
static void filter_add(const char* tag)
|
||||
void debug_filter_add(const char* tag)
|
||||
{
|
||||
const u32 hash = fnv_hash(tag);
|
||||
|
||||
@ -108,11 +108,12 @@ static void filter_add(const char* tag)
|
||||
tags[num_tags++] = hash;
|
||||
}
|
||||
|
||||
static void filter_remove(const char* tag)
|
||||
void debug_filter_remove(const char* tag)
|
||||
{
|
||||
const u32 hash = fnv_hash(tag);
|
||||
|
||||
for(uint i = 0; i < MAX_TAGS; i++)
|
||||
// found it
|
||||
if(tags[i] == hash)
|
||||
{
|
||||
// replace with last element (avoid holes)
|
||||
@ -124,12 +125,18 @@ static void filter_remove(const char* tag)
|
||||
}
|
||||
}
|
||||
|
||||
void debug_filter_clear()
|
||||
{
|
||||
for(uint i = 0; i < MAX_TAGS; i++)
|
||||
tags[i] = 0;
|
||||
}
|
||||
|
||||
static bool filter_allows(const char* text)
|
||||
{
|
||||
uint i;
|
||||
for(i = 0; ; i++)
|
||||
{
|
||||
// .. no colon - should be displayed
|
||||
// no colon found => no tag => should always be displayed
|
||||
if(text[i] == ' ' || text[i] == '\0')
|
||||
return true;
|
||||
if(text[i] == ':' && i != 0)
|
||||
@ -138,7 +145,7 @@ static bool filter_allows(const char* text)
|
||||
|
||||
const u32 hash = fnv_hash(text, i);
|
||||
|
||||
// check if allow-entry is found
|
||||
// check if entry allowing this tag is found
|
||||
for(i = 0; i < MAX_TAGS; i++)
|
||||
if(tags[i] == hash)
|
||||
return true;
|
||||
|
@ -153,19 +153,52 @@ extern enum ErrorReaction debug_assert_failed(const char* file, int line,
|
||||
// we therefore just squelch the warning (unfortunately non-portable).
|
||||
#define debug_warn(str) debug_assert((str) && 0)
|
||||
|
||||
extern void debug_puts(const char* text);
|
||||
extern void debug_putws(const wchar_t* text);
|
||||
|
||||
// write to the debugger output window (may take ~1 ms!)
|
||||
// write a formatted string to the debug channel, subject to filtering
|
||||
// (see below). implemented via debug_puts - see performance note there.
|
||||
extern void debug_printf(const char* fmt, ...);
|
||||
// note: this merely converts to a MBS and calls debug_printf.
|
||||
extern void debug_wprintf(const wchar_t* fmt, ...);
|
||||
|
||||
|
||||
//
|
||||
// filtering
|
||||
//
|
||||
|
||||
// debug output is very useful, but "too much of a good thing can kill you".
|
||||
// we don't want to require different LOGn() macros that are enabled
|
||||
// depending on "debug level", because changing that entails lengthy
|
||||
// compiles and it's too coarse-grained. instead, we require all
|
||||
// strings to start with "tag_string:" (exact case and no quotes;
|
||||
// the alphanumeric-only <tag_string> identifies output type).
|
||||
// they are then subject to filtering: only if the tag has been
|
||||
// "added" via debug_filter_add is the appendant string displayed.
|
||||
//
|
||||
// this approach is easiest to implement and is fine because we control
|
||||
// all logging code. LIMODS falls from consideration since it's not
|
||||
// portable and too complex.
|
||||
//
|
||||
// notes:
|
||||
// - filter changes only affect subsequent debug_*printf calls;
|
||||
// output that didn't pass the filter is permanently discarded.
|
||||
// - strings not starting with a tag are always displayed.
|
||||
// - debug_filter_* can be called at any time and from the debugger.
|
||||
|
||||
// in future, allow output with the given tag to proceed.
|
||||
// no effect if already added.
|
||||
extern void debug_filter_add(const char* tag);
|
||||
// in future, discard output with the given tag.
|
||||
// no effect if not currently added.
|
||||
extern void debug_filter_remove(const char* tag);
|
||||
// clear all filter state; equivalent to debug_filter_remove for
|
||||
// each tag that was debug_filter_add-ed.
|
||||
extern void debug_filter_clear();
|
||||
|
||||
|
||||
// write to memory buffer (fast)
|
||||
// used for "last activity" reporting in the crashlog.
|
||||
extern void debug_wprintf_mem(const wchar_t* fmt, ...);
|
||||
|
||||
// write all logs and <text> out to crashlog.txt (unicode format).
|
||||
// currently all filenames are hardcoded; this may change.
|
||||
extern int debug_write_crashlog(const wchar_t* text);
|
||||
|
||||
|
||||
@ -244,6 +277,11 @@ extern const wchar_t* debug_dump_stack(wchar_t* buf, size_t max_chars, uint skip
|
||||
// helper functions (used by implementation)
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// [system-dependent] write a string to the debug channel.
|
||||
// this can be quite slow (~1 ms)! On Windows, it uses OutputDebugString
|
||||
// (entails context switch), otherwise stdout+fflush (waits for IO).
|
||||
extern void debug_puts(const char* text);
|
||||
|
||||
// abstraction of all STL iterators used by debug_stl.
|
||||
typedef const u8* (*DebugIterator)(void* internal, size_t el_size);
|
||||
|
||||
|
@ -254,7 +254,7 @@ static void importExtensionFunctions()
|
||||
|
||||
static void dump_gl_error(GLenum err)
|
||||
{
|
||||
debug_printf("GL error: ");
|
||||
debug_printf("OGL: ");
|
||||
#define E(e) case e: debug_printf("%s\n", #e); break;
|
||||
switch (err)
|
||||
{
|
||||
|
@ -415,7 +415,7 @@ static void fn_store(HDATA* hd, const char* fn)
|
||||
// fall back to heap alloc.
|
||||
if(!hd->fn)
|
||||
{
|
||||
debug_printf("fn_store: very long filename (%d) %s\n", len, fn);
|
||||
debug_printf("H_MGR: very long filename (%d) %s\n", len, fn);
|
||||
hd->fn = (const char*)malloc(len+1);
|
||||
// still failed - bail (avoid strcpy to 0)
|
||||
if(!hd->fn)
|
||||
@ -721,7 +721,7 @@ static int h_free_idx(i32 idx, HDATA* hd)
|
||||
char buf[H_STRING_LEN];
|
||||
if(vtbl->to_string(hd->user, buf) < 0)
|
||||
strcpy(buf, "(error)"); // safe
|
||||
debug_printf("H_FREE %s %s accesses=%d %s\n", hd->type->name, fn, hd->num_derefs, buf);
|
||||
debug_printf("H_MGR: free %s %s accesses=%d %s\n", hd->type->name, fn, hd->num_derefs, buf);
|
||||
|
||||
fn_free(hd);
|
||||
|
||||
@ -919,6 +919,8 @@ int h_get_refcnt(Handle h)
|
||||
|
||||
void h_mgr_shutdown()
|
||||
{
|
||||
debug_printf("==h_mgr_shutdown== (all handle frees after this are leaks)\n");
|
||||
|
||||
// forcibly close all open handles
|
||||
for(i32 i = 0; i <= last_in_use; i++)
|
||||
{
|
||||
@ -936,9 +938,6 @@ void h_mgr_shutdown()
|
||||
if(!hd->tag)
|
||||
continue;
|
||||
|
||||
if(hd->refs != 0)
|
||||
debug_printf("leaked %s from %s\n", hd->type->name, hd->fn);
|
||||
|
||||
// disable caching; we need to release the resource now.
|
||||
hd->keep_open = 0;
|
||||
hd->refs = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user