mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-30 10:00:14 +01:00
Thomas Sondergaard's API tracer
This commit is contained in:
parent
21fbdb14e9
commit
65ced47453
6 changed files with 579 additions and 0 deletions
30
progs/tools/trace/Makefile
Normal file
30
progs/tools/trace/Makefile
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
# Makefile for Thomas Sondergaard's API tracer
|
||||
|
||||
TOP = ../../..
|
||||
|
||||
include $(TOP)/configs/current
|
||||
|
||||
|
||||
OBJECTS = gltrace.o gltrace_support.o
|
||||
|
||||
TRACER = gltrace.so
|
||||
|
||||
.cc.o:
|
||||
$(CXX) -c $(INCDIRS) $(CXXFLAGS) $< -o $@
|
||||
|
||||
|
||||
default: $(TRACER)
|
||||
|
||||
$(TRACER): $(OBJECTS)
|
||||
$(TOP)/bin/mklib -o $(TRACER) -noprefix -cplusplus \
|
||||
$(MKLIB_OPTIONS) $(OBJECTS)
|
||||
|
||||
gltrace.cc: gltrace.py
|
||||
PYTHONPATH=$(TOP)/src/mesa/glapi python gltrace.py -f $(TOP)/src/mesa/glapi/gl_API.xml > gltrace.cc
|
||||
|
||||
|
||||
clean:
|
||||
rm -f $(OBJECTS)
|
||||
rm -f $(TRACER)
|
||||
rm -f *~
|
||||
rm -f gltrace.cc
|
||||
23
progs/tools/trace/README
Normal file
23
progs/tools/trace/README
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
NAME
|
||||
gltrace - trace opengl calls
|
||||
|
||||
SYNOPSIS
|
||||
gltrace [OPTION] command [arg ...]
|
||||
|
||||
DESCRIPTION
|
||||
-h help (this text)
|
||||
-c log gl calls
|
||||
-t time stamp log entries
|
||||
-e check for and log errors. errors occurring between
|
||||
glBegin() and glEnd() are checked at glEnd()
|
||||
-v verbose. Shows configuration settings passed to
|
||||
gltrace.so
|
||||
-l LOGFILE logfile. Default is stderr
|
||||
|
||||
PROBLEMS
|
||||
Not all OpenGL extensions are known and traced by gltrace. Extension
|
||||
functions not initialized using glXGetProcAddress(ARB) will not be
|
||||
traced.
|
||||
|
||||
AUTHOR
|
||||
Thomas Sondergaard (ts_news1 'at' sondergaard.cc)
|
||||
82
progs/tools/trace/gltrace
Executable file
82
progs/tools/trace/gltrace
Executable file
|
|
@ -0,0 +1,82 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Copyright (C) 2006 Thomas Sondergaard
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||
# copy of this software and associated documentation files (the "Software"),
|
||||
# to deal in the Software without restriction, including without limitation
|
||||
# on the rights to use, copy, modify, merge, publish, distribute, sub
|
||||
# license, and/or sell copies of the Software, and to permit persons to whom
|
||||
# the Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice (including the next
|
||||
# paragraph) shall be included in all copies or substantial portions of the
|
||||
# Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
# IBM AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
# IN THE SOFTWARE.
|
||||
#
|
||||
# Authors:
|
||||
# Thomas Sondergaard <ts@medical-insight.com>
|
||||
|
||||
usage="usage: $0 [ -hctev ] [-l LOGFILE] program [args...]\n\t-h\t\thelp (this text)\n\t-c\t\tlog gl calls\n\t-t\t\ttime stamp log entries\n\t-e\t\tcheck for and log errors. errors occurring between\n\t\t\tglBegin() and glEnd() are checked at glEnd()\n\t-v\t\tverbose. Shows configuration settings passed to\n\t\t\tgltrace.so\n\t-l LOGFILE\tlogfile. Default is stderr"
|
||||
|
||||
# Path to gltrace.so - must not be relative
|
||||
#GLTRACE_SO=/home/ts/Mesa_gltrace/src/mesa/glapi/gltrace.so
|
||||
# This seems to work:
|
||||
GLTRACE_SO=./gltrace.so
|
||||
|
||||
# Set options from command line
|
||||
|
||||
VERBOSE=0
|
||||
GLTRACE_LOG_CALLS=0
|
||||
GLTRACE_LOG_TIME=0
|
||||
GLTRACE_CHECK_ERRORS=0
|
||||
export GLTRACE_LOG_CALLS GLTRACE_LOG_TIME GLTRACE_CHECK_ERRORS
|
||||
|
||||
if [ $# -eq 0 ]; then
|
||||
echo -e $usage
|
||||
exit
|
||||
fi
|
||||
|
||||
while getopts "hctevl:" options; do
|
||||
case $options in
|
||||
h) echo -e $usage
|
||||
exit 1;;
|
||||
c) GLTRACE_LOG_CALLS=1;;
|
||||
t) GLTRACE_LOG_TIME=1;;
|
||||
e) GLTRACE_CHECK_ERRORS=1;;
|
||||
l) GLTRACE_LOGFILE=$OPTARG
|
||||
export GLTRACE_LOGFILE;;
|
||||
v) VERBOSE=1;;
|
||||
*) echo -e $usage
|
||||
exit 1;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Remove the parsed args
|
||||
shift $(($OPTIND-1))
|
||||
|
||||
if [ ! -r $GLTRACE_SO ]; then
|
||||
echo "Error: The gltrace.so file '$GLTRACE_SO' is missing!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
export LD_PRELOAD=$GLTRACE_SO
|
||||
|
||||
if [ $VERBOSE -eq 1 ]; then
|
||||
echo GLTRACE_LOG_CALLS=$GLTRACE_LOG_CALLS
|
||||
echo GLTRACE_LOG_TIME=$GLTRACE_LOG_TIME
|
||||
echo GLTRACE_CHECK_ERRORS=$GLTRACE_CHECK_ERRORS
|
||||
echo GLTRACE_LOGFILE=$GLTRACE_LOGFILE
|
||||
echo LD_PRELOAD=$LD_PRELOAD
|
||||
echo command=$*
|
||||
fi
|
||||
|
||||
exec $*
|
||||
189
progs/tools/trace/gltrace.py
Normal file
189
progs/tools/trace/gltrace.py
Normal file
|
|
@ -0,0 +1,189 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
# Copyright (C) 2006 Thomas Sondergaard
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||
# copy of this software and associated documentation files (the "Software"),
|
||||
# to deal in the Software without restriction, including without limitation
|
||||
# on the rights to use, copy, modify, merge, publish, distribute, sub
|
||||
# license, and/or sell copies of the Software, and to permit persons to whom
|
||||
# the Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice (including the next
|
||||
# paragraph) shall be included in all copies or substantial portions of the
|
||||
# Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
# IBM AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
# IN THE SOFTWARE.
|
||||
#
|
||||
# Authors:
|
||||
# Thomas Sondergaard <ts@medical-insight.com>
|
||||
|
||||
import gl_XML, glX_XML, glX_proto_common, license
|
||||
import sys, getopt, copy, string
|
||||
|
||||
def create_argument_string(parameters):
|
||||
"""Create a parameter string from a list of gl_parameters."""
|
||||
|
||||
list = []
|
||||
for p in parameters:
|
||||
list.append( p.name )
|
||||
#if len(list) == 0: list = ["void"]
|
||||
|
||||
return string.join(list, ", ")
|
||||
|
||||
def create_logfunc_string(func, name):
|
||||
"""Create a parameter string from a list of gl_parameters."""
|
||||
|
||||
list = []
|
||||
list.append('"gl' + name + '("')
|
||||
sep = None
|
||||
for p in func.parameters:
|
||||
if (sep):
|
||||
list.append(sep)
|
||||
list.append( p.name )
|
||||
sep = '", "'
|
||||
list.append('");"')
|
||||
#if len(list) == 0: list = ["void"]
|
||||
|
||||
return "if (config.logCalls) GLTRACE_LOG(" + string.join(list, " << ")+");";
|
||||
|
||||
class PrintGltrace(glX_proto_common.glx_print_proto): #(gl_XML.gl_print_base):
|
||||
def __init__(self):
|
||||
gl_XML.gl_print_base.__init__(self)
|
||||
|
||||
self.name = "gltrace.py"
|
||||
self.license = license.bsd_license_template % ( \
|
||||
"""Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
|
||||
(C) Copyright IBM Corporation 2004""", "PRECISION INSIGHT, IBM")
|
||||
#self.header_tag = "_INDIRECT_H_"
|
||||
|
||||
self.last_category = ""
|
||||
return
|
||||
|
||||
|
||||
def printRealHeader(self):
|
||||
print """/**
|
||||
* \\file
|
||||
* gl and glX wrappers for tracing
|
||||
*
|
||||
* \\author Thomas Sondergaard <ts@medical-insight.com>
|
||||
*/
|
||||
"""
|
||||
#self.printVisibility( "HIDDEN", "hidden" )
|
||||
#self.printFastcall()
|
||||
#self.printNoinline()
|
||||
|
||||
print """
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glx.h>
|
||||
#include <GL/glu.h>
|
||||
#include <dlfcn.h>
|
||||
#include "gltrace_support.h"
|
||||
|
||||
using namespace gltrace;
|
||||
|
||||
static GLenum real_glGetError() {
|
||||
static GLenum (*real_func)(void) = 0;
|
||||
if (!real_func) real_func = (GLenum (*)(void)) dlsym(RTLD_NEXT, "glGetError");
|
||||
return real_func();
|
||||
}
|
||||
|
||||
bool betweenGLBeginEnd = false;
|
||||
|
||||
extern "C" {
|
||||
|
||||
|
||||
__GLXextFuncPtr real_glXGetProcAddressARB(const GLubyte *func_name) {
|
||||
static __GLXextFuncPtr (*real_func)(const GLubyte *func_name) = 0;
|
||||
if (!real_func) real_func = (__GLXextFuncPtr (*)(const GLubyte *func_name)) dlsym(RTLD_NEXT, "glXGetProcAddressARB");
|
||||
|
||||
return real_func(func_name);
|
||||
}
|
||||
|
||||
__GLXextFuncPtr glXGetProcAddressARB(const GLubyte *func_name_ubyte) {
|
||||
std::string func_name =
|
||||
std::string("gltrace_")+reinterpret_cast<const char*>(func_name_ubyte);
|
||||
|
||||
__GLXextFuncPtr f = (__GLXextFuncPtr) dlsym(RTLD_DEFAULT, func_name.c_str());
|
||||
if (!f) {
|
||||
GLTRACE_LOG("warning: Could not resolve '" << func_name << "' - function will not be intercepted");
|
||||
return real_glXGetProcAddressARB(func_name_ubyte);
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
||||
"""
|
||||
|
||||
def printRealFooter(self):
|
||||
print "} // Extern \"C\""
|
||||
|
||||
def printBody(self, api):
|
||||
for func in api.functionIterateGlx():
|
||||
for func_name in func.entry_points:
|
||||
functionPrefix = ""
|
||||
use_dlsym = True
|
||||
if (api.get_category_for_name(func.name)[1] != None):
|
||||
functionPrefix = "gltrace_"
|
||||
use_dlsym = False
|
||||
|
||||
print '%s %sgl%s(%s) {' % (func.return_type, functionPrefix, func_name, func.get_parameter_string())
|
||||
if (use_dlsym):
|
||||
print ' static %s (*real_func)(%s) = 0;' % (func.return_type, func.get_parameter_string())
|
||||
print ' if (!real_func) real_func = (%s (*)(%s)) dlsym(RTLD_NEXT, "gl%s");' % (func.return_type, func.get_parameter_string(), func_name)
|
||||
else: # use glXGetProcAddressArb
|
||||
print ' static %s (*real_func)(%s) = 0;' % (func.return_type, func.get_parameter_string())
|
||||
print ' if (!real_func) real_func = (%s (*)(%s)) real_glXGetProcAddressARB((GLubyte *)"gl%s");' % (func.return_type, func.get_parameter_string(), func_name)
|
||||
print ' ' + create_logfunc_string(func, func_name)
|
||||
if (func.return_type == "void"):
|
||||
print ' real_func(%s);' % (create_argument_string(func.parameters))
|
||||
else:
|
||||
print ' %s retval = real_func(%s);' % (func.return_type, create_argument_string(func.parameters))
|
||||
if (func.name == "Begin"):
|
||||
print ' betweenGLBeginEnd = true;'
|
||||
elif (func.name == "End"):
|
||||
print ' betweenGLBeginEnd = false;'
|
||||
print ' if (!betweenGLBeginEnd && config.checkErrors) {'
|
||||
print ' GLenum res;'
|
||||
print ' while ((res = real_glGetError ()) != GL_NO_ERROR) '
|
||||
print ' GLTRACE_LOG("OpenGL Error (" << res << "): <" << gluErrorString(res) << "> at " << gltrace::getStackTrace());'
|
||||
print ' }'
|
||||
if (func.return_type != "void"):
|
||||
print " return retval;"
|
||||
print '}'
|
||||
|
||||
|
||||
def show_usage():
|
||||
print "Usage: %s [-f input_file_name] [-m output_mode] [-d]" % sys.argv[0]
|
||||
print " -m output_mode Output mode can be one of 'proto', 'init_c' or 'init_h'."
|
||||
print " -d Enable extra debug information in the generated code."
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
file_name = "gl_API.xml"
|
||||
|
||||
try:
|
||||
(args, trail) = getopt.getopt(sys.argv[1:], "f:d")
|
||||
except Exception,e:
|
||||
show_usage()
|
||||
|
||||
debug = 0
|
||||
for (arg,val) in args:
|
||||
if arg == "-f":
|
||||
file_name = val
|
||||
elif arg == "-d":
|
||||
debug = 1
|
||||
|
||||
printer = PrintGltrace()
|
||||
|
||||
printer.debug = debug
|
||||
api = gl_XML.parse_GL_API( file_name, glX_XML.glx_item_factory() )
|
||||
|
||||
printer.Print( api )
|
||||
190
progs/tools/trace/gltrace_support.cc
Normal file
190
progs/tools/trace/gltrace_support.cc
Normal file
|
|
@ -0,0 +1,190 @@
|
|||
/*
|
||||
* Copyright (C) 2006 Thomas Sondergaard All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "gltrace_support.h"
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#include <execinfo.h>
|
||||
#include <cxxabi.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
namespace {
|
||||
|
||||
const char *
|
||||
demangle (const char * mangled) throw()
|
||||
{
|
||||
static char buf[4096];
|
||||
int status;
|
||||
unsigned int length = sizeof(buf)-1;
|
||||
|
||||
memset (buf, 0, sizeof(buf));
|
||||
|
||||
if (!mangled)
|
||||
return 0;
|
||||
|
||||
char * demangled = __cxxabiv1::__cxa_demangle(mangled,
|
||||
buf,
|
||||
&length,
|
||||
&status);
|
||||
if (demangled && !status)
|
||||
return demangled;
|
||||
else
|
||||
return mangled;
|
||||
}
|
||||
|
||||
void
|
||||
printStackTrace (void **stackframes,
|
||||
int stackframe_size,
|
||||
std::ostream & out )
|
||||
{
|
||||
char **strings = 0;
|
||||
std::stringstream ss;
|
||||
|
||||
// this might actually fail if memory is tight or we are in a
|
||||
// signal handler
|
||||
strings = backtrace_symbols (stackframes, stackframe_size);
|
||||
|
||||
ss << "Backtrace :";
|
||||
|
||||
if (stackframe_size == gltrace::MAX_STACKFRAMES)
|
||||
ss << "(possibly incomplete maximal number of frames exceeded):" << std::endl;
|
||||
else
|
||||
ss << std::endl;
|
||||
|
||||
out << ss.str();
|
||||
|
||||
// the first frame is the constructor of the exception
|
||||
// the last frame always seem to be bogus?
|
||||
for (int i = 0; strings && i < stackframe_size-1; ++i) {
|
||||
char libname[257], funcname[2049];
|
||||
unsigned int address=0, funcoffset = 0x0;
|
||||
|
||||
memset (libname,0,sizeof(libname));
|
||||
memset (funcname,0,sizeof(funcname));
|
||||
|
||||
strcpy (funcname,"??");
|
||||
strcpy (libname, "??");
|
||||
|
||||
int scanned = sscanf (strings[i], "%256[^(] ( %2048[^+] + %x ) [ %x ]",
|
||||
libname,
|
||||
funcname,
|
||||
&funcoffset,
|
||||
&address);
|
||||
|
||||
/* ok, so no function was mentioned in the backtrace */
|
||||
if (scanned < 4) {
|
||||
scanned = sscanf (strings[i], "%256[^([] [ %x ]",
|
||||
libname,
|
||||
&address);
|
||||
}
|
||||
|
||||
if (funcname[0] == '_') {
|
||||
const char * demangled;
|
||||
if ((demangled = demangle(funcname) ) != funcname) {
|
||||
strncpy (funcname, demangled, sizeof(funcname)-1);
|
||||
}
|
||||
}
|
||||
else
|
||||
strcat (funcname," ()");
|
||||
|
||||
out << "\t#" << i << std::hex << " 0x" << address << " in " << funcname
|
||||
<< " at 0x" << funcoffset << " (from " << libname << ")" << std::endl;
|
||||
}
|
||||
|
||||
free (strings);
|
||||
}
|
||||
|
||||
|
||||
} // anon namespace
|
||||
|
||||
namespace gltrace {
|
||||
|
||||
std::string getStackTrace(int count, int first) {
|
||||
++first;
|
||||
std::stringstream ss;
|
||||
const int BA_MAX = 1000;
|
||||
assert(count + first <= BA_MAX);
|
||||
void *ba[BA_MAX];
|
||||
int n = backtrace(ba, count+first);
|
||||
|
||||
printStackTrace( &ba[first], n-first, ss);
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::ostream &timeNow(std::ostream &os) {
|
||||
|
||||
struct timeval now;
|
||||
struct tm t;
|
||||
static char *months[12] =
|
||||
{
|
||||
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
||||
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
|
||||
};
|
||||
|
||||
gettimeofday (&now, 0);
|
||||
localtime_r ((time_t*) &now.tv_sec, &t);
|
||||
|
||||
os
|
||||
<< months[t.tm_mon] << " "
|
||||
<< std::setw(2) << t.tm_mday << " "
|
||||
<< std::setw(2) << t.tm_hour << ":"
|
||||
<< std::setw(2) << t.tm_min << ":"
|
||||
<< std::setw(2) << t.tm_sec << "."
|
||||
<< std::setw(3) << now.tv_usec/1000;
|
||||
return os;
|
||||
}
|
||||
|
||||
logstream::logstream(const char *filename) {
|
||||
if (!filename)
|
||||
init(std::cerr.rdbuf());
|
||||
else {
|
||||
file_os.reset(new std::ofstream(filename));
|
||||
if (file_os->good())
|
||||
init(file_os->rdbuf());
|
||||
else {
|
||||
std::cerr << "ERROR: gltrace: Failed to open '" << filename
|
||||
<< "' for writing. Falling back to stderr." << std::endl;
|
||||
init(std::cerr.rdbuf());
|
||||
}
|
||||
}
|
||||
*this << std::setfill('0'); // setw used in timeNow
|
||||
}
|
||||
|
||||
|
||||
Config::Config() :
|
||||
logCalls(true),
|
||||
checkErrors(true),
|
||||
logTime(true),
|
||||
log(getenv("GLTRACE_LOGFILE")) {
|
||||
if (const char *v = getenv("GLTRACE_LOG_CALLS"))
|
||||
logCalls = strncmp("1", v, 1) == 0;
|
||||
if (const char *v = getenv("GLTRACE_CHECK_ERRORS"))
|
||||
checkErrors = strncmp("1", v, 1) == 0;
|
||||
if (const char *v = getenv("GLTRACE_LOG_TIME"))
|
||||
logTime = strncmp("1", v, 1) == 0;
|
||||
}
|
||||
|
||||
// *The* config
|
||||
Config config;
|
||||
|
||||
} // namespace gltrace
|
||||
65
progs/tools/trace/gltrace_support.h
Normal file
65
progs/tools/trace/gltrace_support.h
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
// -*- c++ -*- (emacs c++ mode)
|
||||
/*
|
||||
* Copyright (C) 2006 Thomas Sondergaard All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef GLTRACE_SUPPORT_H
|
||||
#define GLTRACE_SUPPORT_H
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
|
||||
namespace gltrace {
|
||||
|
||||
const int MAX_STACKFRAMES = 100;
|
||||
|
||||
/// Returns the stack trace of the current thread
|
||||
std::string getStackTrace(int count = MAX_STACKFRAMES, int first = 0);
|
||||
|
||||
std::ostream &timeNow(std::ostream &os);
|
||||
|
||||
struct logstream : public std::ostream {
|
||||
|
||||
/// Opens a logstream - if filename is null, stderr will be used
|
||||
logstream(const char *filename = 0);
|
||||
|
||||
private:
|
||||
std::auto_ptr<std::ofstream> file_os;
|
||||
};
|
||||
|
||||
struct Config {
|
||||
bool logCalls;
|
||||
bool checkErrors;
|
||||
bool logTime;
|
||||
logstream log;
|
||||
|
||||
Config();
|
||||
};
|
||||
|
||||
extern Config config;
|
||||
|
||||
} // namespace gltrace
|
||||
|
||||
#define GLTRACE_LOG(x) \
|
||||
{ if (config.logTime) config.log << timeNow << ": "; config.log << x << "\n"; }
|
||||
|
||||
#endif // GLTRACE_SUPPORT_H
|
||||
|
||||
|
||||
Loading…
Add table
Reference in a new issue