Bugle user manual


Table of Contents

1. Introduction
2. Installing Bugle
2.1. Requirements
2.2. Configuring
2.2.1. Configuring for cross-compilation
2.3. Compiling and installing
2.4. Compiling on Windows
3. Using bugle with OpenGL ES
3.1. Introduction
3.2. Configuration
3.3. Installation
4. Extending bugle
4.1. Introduction
4.2. API and ABI compatibility
4.3. Guidelines
4.3.1. Coding style
4.3.2. OpenGL contexts and threads
4.3.3. OpenGL extensions
4.4. Compiling an external filter-set library
4.5. Concepts
4.5.1. Callbacks, filter-sets, filters and libraries
4.5.2. Loading and activation
4.5.3. Budgie
4.5.4. Functions and groups
4.6. Basic filter-set API
4.6.1. Library initialisation
4.6.2. Filter-set variables
4.6.3. Filter-set initialisation and destruction
4.6.4. Writing callbacks
4.7. Object shadowing
4.7.1. Concepts
4.7.2. Class management functions
4.7.3. Object management functions
4.7.4. Thread safety
4.8. Utility functions and filter-sets
4.8.1. Begin/end checking
4.8.2. Error checking
4.8.3. Making calls to OpenGL
4.8.4. Checking for OpenGL extensions
5. Hacking bugle
5.1. Porting
5.1.1. Introduction
5.1.2. Binary format
5.1.3. Operating system API
5.1.4. Windowing system
5.1.5. GL-Windowing integration
5.1.6. Filesystem layout
A. Bugle debugger protocol
A.1. Introduction
A.2. Basics
A.2.1. Types
A.2.2. States
A.3. Requests
A.3.1. Run
A.3.2. Continue
A.3.3. Step
A.3.4. Break on function
A.3.5. Break on event
A.3.6. Break on error
A.3.7. Stop
A.3.8. Quit
A.3.9. Filter-set activation and deactivation
A.3.10. State requests
A.3.11. Data requests
A.4. Synchronous responses
A.4.1. Error
A.4.2. Answer
A.4.3. Running
A.4.4. Binary state dumps
A.4.5. Textual state dumps
A.4.6. Data responses
A.5. Asynchronous responses
A.5.1. Break
A.5.2. Break on event
A.6. Protocol definition
B. FAQ
B.1. Compiling
B.2. Running
B.3. Miscellaneous
C. Bugle manual pages
bugle — An OpenGL debugging library
bugle-statistics — specify formulae and metadata for bugle statistics
gldb-gui — graphical OpenGL debugger
gldb — console-based OpenGL debugger
bugle-camera — allow the camera to be manipulated
bugle-checks — check for errors that OpenGL defines as undefined behaviour
bugle-eps — captures vector graphics representatios of scenes
bugle-error — detect errors in OpenGL calls
bugle-exe — record a compilable log of OpenGL calls made
bugle-extoverride — hide OpenGL extensions from an application
bugle-frontbuffer — force rendering to the front buffer
bugle-log — configure logging output from other filter-sets
bugle-logstats — log statistics to file
bugle-screenshot — takes screenshots and captures video
bugle-showerror — reports errors in OpenGL calls
bugle-showextensions — show which extensions are used by an OpenGL application
bugle-showstats — render statistics over the display
bugle-stats_basic — gather frame rate statistics
bugle-stats_calls — gather call frequency count
bugle-stats_calltimes — gather call timing
bugle-stats_fragments — gather fragment counts
bugle-stats_nv — gather performance data from NVPerfSDK
bugle-stats_primitives — gather triangle and batch counts
bugle-trace — record a log of OpenGL calls made
bugle-unwindstack — recover a stack trace after a segmentation fault
bugle-wireframe — force rendering in wireframe mode
D. Release notes
E. Change Log

List of Tables

4.1. Filter-set variable types

Chapter 1. Introduction

Bugle is an toolkit for debugging and profiling OpenGL applications running on UNIX-like systems. It consists of two parts: a collection of filter-sets that observe and sometimes modify calls to the OpenGL API, and a graphical debugger that helps in examining state, setting breakpoints, and capturing errors.

Bugle is still in active development, and is considered alpha. What this means is that while there are a lot of features, any given one of them might be broken on any given day. If you do find a bug, please let me know ().

To get started with bugle, first read the installation instructions, and refer to the FAQ if you run into any problems. If you just want to use the debugger, you can skip straight to its manual page. Otherwise, start with the overview manual page for bugle to learn how to use it, then find the filter-sets you want in the reference manual.

Chapter 2. Installing Bugle

2.1. Requirements

Bugle is intended to work on any POSIX-compliant operating system that use the X Windowing System, dynamic linking, and LD_PRELOAD for library interposition. If it fails to work on such an operating system, please let me know (I only use it on GNU/Linux). It is also supported on Windows, although this support is less complete. It also includes highly experimental and incomplete support for OpenGL ES 2 on Windows.

The following packages are required to compile bugle:

  • GCC, at least version 3.2, and not 4.0 (see the FAQ for an explanation of why).

  • A C++ compiler (generally g++)

  • OpenGL header files, including a recent version of glext.h. A version supporting at least OpenGL 2.0 is required. For OpenGL ES 2, the OpenGL ES 2 and EGL header files are required.

  • Perl 5

The following packages are not required, but if present, will enable extra functionality:

readline

This will enable line editing in the console debugger. The GUI debugger is the preferred method of debugging.

GTK+

This is needed for the GUI debugger.

gtkglext

This is needed for the texture and framebuffer viewers in the GUI debugger.

GLEW

GLEW is also needed for texture and framebuffer viewers.

FFmpeg

If FFmpeg is available, the included libavcodec is used for video capture.

2.2. Configuring

Bugle uses the standard configure command for compile-time configuration. Generic instructions may be found in INSTALL in the root of the source directory. In general, configure will auto-detect optional packages and use them only if present, but you can also prevent it from depending on certain packages with the following flags. FFmpeg (lavc) in particular is a moving target and if you get compilation failures, you should try disabling it.

  • --without-lavc

  • --without-readline

  • --without-gtk

  • --without-gtkglext

Bugle does not use threads itself, but applications that it debugs might, and bugle needs to use appropriate locking and thread-local storage libraries. The correct option should be auto-detected, but you can force it with --enable-threads=model. Valid models are posix and win32.

Finally, bugle intercepts events from X11 and Windows. While there are no known cases of this causing problems, it is difficult to make the interception completely transparent, and so the --disable-input option is available to disable it at compile time. It is also required when using EGL on a platform other than X11 or Windows.

2.2.1. Configuring for cross-compilation

If possible, the best way to do cross-compilation is to use scratchbox, where it should all work seamlessly. However, scratchbox only supports a limited set of cross-compilation targets. If you want to do cross-compilation, you will need to jump through some extra hoops.

First, run configure in the top-level directory, passing the appropriate --host option for your cross-compiler. Also make sure that the appropriate header files and libraries for the cross-compilation target are available. You might also need to pass extra options to configure to disable optional features that are incorrectly detected (see above).

Next, change into the budgie subdirectory and run the configure script there (if you are configuring in a different directory from the source, you will need to be in the budgie subdirectory of the build directory, running the configure script from the budgie subdirectory of the source. When doing this, configure for your native compiler. This is necessary because the program that is built in this directory is run on the build machine to produce source code, not on the host.

2.3. Compiling and installing

Compilation is as simple as running make. Before installing, you should remove any previous installation of bugle to avoid leaving old versions of files around. If you do not have your original installation tree to run make uninstall, you should at least remove the files in /usr/local/lib/bugle and /usr/local/lib/libbugle*. To install the new version, run make install as root.

Next, you need to install some files for the user that will run bugle. Create a directory $HOME/.bugle, and copy doc/examples/filters and doc/examples/statistics into it.

2.4. Compiling on Windows

Installing from source on Windows is supported, but it is significantly trickier than on UNIX-like systems, and currently only recommended for experts. The intended target is MinGW; you can try using Cygwin as well, but it is not tested.

Here is the list of steps I used to install on Windows, including support for the debugger. The versions numbers were the latest available at the time, but newer versions should work too.

  1. Install MinGW 5.1.4, including GCC and G++, but not make.

  2. Install MSYS 1.0.10.

  3. Install msysDTK 1.0.1. Alternatively, if you have Cygwin installed, add Cygwin's bin directory to the end of PATH.

  4. Downloaded mingw-libgnurx-2.5.1-bin.tar.gz and mingw-libgnurx-2.5.1-dev.tar.gz from the MinGW page, and unpacked both into /mingw (i.e., the directory in which MinGW is installed).

  5. Download the GTK+ bundle (2.12.11) from gtk.org, and unpack it into /mingw.

  6. Get the gtkglext installer from http://www.bonifazi.eu/appunti/, and install it into /mingw.

  7. Download the source for GLEW 1.5 and unpack it into a temporary location and built it using make, then install it with the command make GLEW_DEST=/mingw install.

  8. Grab the latest glext.h and wglext.h headers, and put them in /mingw/include/GL.

After installation, you will have a opengl32.dll file installed. When debugging a program, you need to place this on the path ahead of the real one. This can be achieved by copying it to the same directory as the program you intend to debug.

Chapter 3. Using bugle with OpenGL ES

3.1. Introduction

bugle has partial support for OpenGL ES. The OpenGL ES 2.0 support has been tested using the AMD OpenGL ES Emulator 1.3, and OpenGL ES 1.1 support has been tested on a hardware platform. OpenGL ES 1.0 support has not been tested and is probably broken. For OpenGL ES 1.x, only the Common (CM) profile is supported.

The testing shows that basic features work. These include tracing, and the debugger using breakpoints, examining state, and examining shaders. Texture and buffer viewing does not currently work (due to limitations of the query mechanisms in OpenGL ES). Many of the filtersets do not work, either because they intrinsicly depend on features excluded from OpenGL ES, or because they have not yet been ported. The test suite is not supported.

It should be noted that when using an emulator that works on top of OpenGL, an alternative approach to debugging is to use bugle as a regular (desktop) OpenGL debugger. This will reveal data such as textures and framebuffers. However, it cannot access the error checking that is done in the emulation layer. For example, an INVALID_ENUM error will not be caught by the debugger if it is generated entirely within the emulation layer.

Support on top of X11 rather than Windows is theoretically present and compiles, but has not been tested. Feedback from anyone with a working OpenGL ES implementation on an X11 system is welcomed.

3.2. Configuration

Configuration can be done largely as described in Section 2.2, “Configuring”. To indicate that OpenGL ES is desired, --with-target=config must be passed to configure, where config is one of the values below:

gles1cm-egl-posix

OpenGL ES 1.x Common profile with EGL on a UNIX-like operating system (only tested with GNU/Linux).

gles1cm-legacy-egl-win

OpenGL ES 1.x Common profile with EGL on a Windows system. This is set up for the legacy integration guidelines, with a single library (libGLES_CM.so) containing both EGL and OpenGL ES functions, and using the __cdecl calling convention.

gles2-egl-posix

OpenGL ES 2.x with EGL on a UNIX-like operating system (untested).

gles2-egl-win

OpenGL ES 2.x with EGL on Windows

Note

Desktop OpenGL header files and libraries are still required for the GUI debugger.

Note

Currently OpenGL ES 1.x on Windows is not supported, but this can easily be added.

You also need to ensure that your various paths are set correctly. The headers, libraries and DLLs for the OpenGL ES implementation need to be listed in CPATH, LIBRARY_PATH and PATH respectively, unless the compiler is already configured to find them.

3.3. Installation

Apart from the usual installation step, some extra setup is required on a Windows system when using OpenGL ES 2.0, due to the limitations of the dynamic linker. Create copies of the system libEGL.dll and libGLESv2.dll called bglEGL.dll and bglGLESv2.dll respectively. Then modify each of these files so that links to the other use the replacement name. This can be done as follows, although you might find that the version of sed provided with MSYS is too old:

$ sed -b 's/libGLESv2/bglGLESv2/g' libEGL.dll > bglEGL.dll
$ sed -b 's/libEGL/bglEGL/g' libGLESv2.dll > bglGLESv2.dll

You should check that the new files are exactly the same size as the originals. Next, make sure that the versions of libEGL.dll and libGLESv2.dll installed by bugle are the first on the path, and that the renamed libraries you generated are also on the path.

Chapter 4. Extending bugle

4.1. Introduction

This chapter is aimed at developers who wish to implement new filter-sets for bugle. Bugle uses a module system to make this relatively easy to do without making intrusive changes to the base system.

It is also worth reading for anyone interested in hacking on the bugle core.

4.2. API and ABI compatibility

The API has been designed so that filter-sets can be maintained separately from bugle, even if the filter-set depends on OpenGL extensions that were not available at the time bugle was compiled. It has also been designed so that installing a newer (or older) version of bugle will not necessarily break separately installed filter-sets purely because the set of OpenGL headers has changed.

Warning

The API is still changing regularly and there is room for optimisation, so upgrades to bugle may break the API or ABI.

4.3. Guidelines

This section contains stylistic guidelines and best practices. You should follow them if you hope to get your filter-sets included in the bugle source code, or want them to be generally useful to other users.

4.3.1. Coding style

  • Indenting is four spaces.

  • Use spaces not tabs.

  • Both opening and closing braces go on their own line.

  • Function return types go on the same line as the rest of the prototype.

  • Filter-sets, and any other code that will be preloaded into a user program, should link against as few libraries as possible, since if the user program uses a different version there will be conflicts. As a result, C++ code cannot be used if it links against libstdc++.

  • Functions that act on type should be named type, _action. See below for when to prefix the name with bugle_.

  • Names of types should generally not have a bugle_ prefix, unless it is needed to clearly disambiguate it. This is an area where consistency could be improved.

  • Functions in the core code should have a bugle_ prefix if and only if they are meant to be called from filter-sets or from the debugger. Such functions are generally safe for filter-sets to use unless marked otherwise.

  • A constructor for a type that returns a malloced instance should be named type_new, whereas a constructor that modifies existing memory is called type_init. The corresponding destructors are type_free and type_clear. For a module of code, initialisation and shutdown functions should be named module_initialise (note spelling) and module_shutdown. This in particular applies to filter-sets.

  • Functions in filter-sets should be declared static, unless they are to be exported to other filter-sets. These functions must have some vendor prefix. This is bugle_ for the filter-sets distributed with bugle, but should be something else for other filter-sets to avoid conflicts.

  • C files should contain conforming C89 syntax as far as possible. That means no variable initialisers, no variable-length arrays, and no C++-style (//) comments.

  • POSIX, BSD and X/OPEN library functions are acceptable if the appropriate feature macros are defined (_POSIX_C_SOURCE and so on). For filter-sets distributed with bugle, gnulib should be used for memory-allocating functions (xmalloc and xasprintf, for example) and for non-portable functions. Unfortunately, gnulib symbols cannot be exported since they may conflict with different implementations in the debugged application.

4.3.2. OpenGL contexts and threads

Most of the state in OpenGL is associated with a particular context. Each thread may have a different current context, or no context. Each context can be current in at most one thread. You should keep this in mind when you attempt to track any particular OpenGL state. If you are using a global variable then your code is almost certainly not correct for multi-threaded or multi-context applications.

The object sub-system in bugle makes it easy to associate data with a particular context, and is the recommended method.

4.3.3. OpenGL extensions

BuGLe tries to support systems that only have runtime support for OpenGL 1.1, to support the Windows software rasteriser. However, as of July 2008, a glext.h supporting OpenGL 2.0 is a requirement, so you may assume that the reflection system knows about these functions. For any post-2.0 functions, you should favour the BUDGIE_GROUP_ID(glFunction) definition with the oldest name, which is generally an extension function. You should also protect any such code with a test for the GL extension define e.g., GL_ARB_multitexture.

4.4. Compiling an external filter-set library

At present there are no aclocal macros to set up bugle, but there is a pkg-config configuration file. Note that with the default install paths for bugle, not all pkg-config installations will look in the right place. You might need to set PKG_CONFIG to something like /usr/local/lib/pkgconfig.

Apart from the basic CFLAGS and LDFLAGS extracted from pkg-config, you should also ensure that your module is compiled with suitable flags to make it thread-safe. Using libtool is recommended, in which case you should use the -thread-safe.

The installation directory can also be extracted from pkg-config:

pkg-config --variable=filterdir bugle

4.5. Concepts

4.5.1. Callbacks, filter-sets, filters and libraries

The mechanisms for intercepting and modifying OpenGL function calls are arranged in a four-level hierarchy. From largest to smallest, these are:

  • Filter libraries, which are a loose collection of filter-sets. These allow filter-sets to be grouped together to avoid having hundreds of files. It also makes shared access to data easier.

  • Filter-sets, which are tightly coupled groups of filters. Each filter-set may have state, may depend upon other filter-sets and may only be loaded or unloaded as a unit.

  • Filters, which are used to control sequencing. For example, some filter-sets need to have some code run before calls are executed and other code after. These pieces of code would be placed in separate filters. The plugin author may list ordering dependencies between filters.

  • Callbacks, which are the actual functions that act on calls. A filter may register multiple callbacks, each of which acts on some subset of the possible calls.

4.5.2. Loading and activation

In order to allow modifiers to be turned on or off on the fly, there is a distinction between loading and activation. All filter-sets listed in the chain are loaded, but should alter the behaviour of the program only when active. Filter-sets are loaded only at startup and unloaded at program termination, but can be activated or deactivated arbitrarily. Most callbacks are only called when the filter-set is active, but it is possible to register callbacks that are called even when the filter-set is inactive. This allows the filter-set to monitor state so that it can do the right thing during activation, or to execute cleanup code after deactivation.

4.5.3. Budgie

Budgie is the module within bugle that generates huge amounts of code automatically. Apart from the code to override each OpenGL function, it also generates a lot of reflection information about functions and types. The API for the generated code isn't currently documented. Refer to existing filter-sets or to the header files in include/budgie.

4.5.4. Functions and groups

In bugle terminology, a function is simply an OpenGL function. Both glActiveTexture and glActiveTextureARB are functions, and they are referred to internally by the symbols FUNC_glActiveTexture and FUNC_glActiveTextureARB respectively.

At this point, you're probably thinking but they're the same function! Bugle deals with this using groups, which are sets of functions with different names but the same signatures and semantics. The group that contains these two functions may be referred to as either GROUP_glActiveTexture or GROUP_glActiveTextureARB. The symbols expand to the same value.

The values of these symbols can change every time the OpenGL headers are modified, so the symbols should not be used in filter-sets (in fact, the corresponding headers are not even installed by bugle). Instead, you should use budgie_function_name, budgie_function_id and budgie_function_group to map between these numbers and symbolic names on the fly. If you know the name of the function as a literal piece of text at compile time, you can write, for example, BUDGIE_FUNCTION_ID(glGetString) to get the symbol for glGetString. At present this simply wraps budgie_function_id with a cache variable, but in future there may be further optimisations. In core code that includes budgielib/defines.h, this macro reduces to FUNC_glGetString. There are similar macros BUDGIE_GROUP_ID and BUDGIE_TYPE_ID.

4.6. Basic filter-set API

4.6.1. Library initialisation

Each library must contain an initialisation function with the following signature:

void bugle_initialise_filter_library(void);

This is the literal name of the function. It will be called by bugle's loader code, and you should not mark it as a constructor or anything similar. Note that it will always be called, even if the corresponding filter-sets are not requested by the user.

This function does any global initialisation required, registers filter-sets, and registers ordering requirements between filter-sets:

#include <bugle/filters.h>
                    
filter_set *bugle_filter_set_new(filter_set_info *info);

The filter_set_info must be constant and have global lifetime, since bugle will continue to refer to it after the call returns. It has the following fields:

typedef struct
{
    const char *                     name;
    filter_set_loader                load;
    filter_set_unloader              unload;
    filter_set_activator             activate;
    filter_set_deactivator           deactivate;
    const filter_set_variable_info * variables;
    const char *                     help;
} filter_set_info;

The fields have the following meanings:

name

The name of the filter-set, as it will appear in ~/.bugle/filters.

load, unload, activate, deactivate

Callback functions that are used to load, unload, activate and deactivate the filter-set. They are described in more detail in Section 4.6.3, “Filter-set initialisation and destruction”.

variables

An array describing the variables that may be configured by the user. This is described in Section 4.6.2, “Filter-set variables”.

help

A one-line description of the filter-set, which is displayed if an unknown chain is requested by the user.

4.6.2. Filter-set variables

Many filter-sets are configurable via variables that are set in the configuration file. The variables field of a filter_set_info points to an array of filter_set_variable_info structures, which have the following format:

typedef struct
{
    const char *             name;
    const char *             help;
    filter_set_variable_type type;
    void *                   value;
    bool                   (*callback)(const filter_set_variable_info *var, const char *text, const void *value);
} filter_set_info;

The name and help fields have the same use as they do in filter_set_info. The type is one of the enumerants in Table 4.1, “Filter-set variable types”.

Table 4.1. Filter-set variable types

EnumerantC typeChecks
FILTER_SET_VARIABLE_BOOLbool 
FILTER_SET_VARIABLE_INTlong 
FILTER_SET_VARIABLE_UINTlong≥ 0
FILTER_SET_VARIABLE_POSITIVE_INTlong> 0
FILTER_SET_VARIABLE_FLOATfloatfinite
FILTER_SET_VARIABLE_STRINGchar * 
FILTER_SET_VARIABLE_KEYbugle_input_keyvalid
FILTER_SET_VARIABLE_CUSTOMany 

With the exception of the FILTER_SET_VARIABLE_CUSTOM type, each enumerant corresponds to a C type. Set the value field to a pointer to a C variable of this type, and it will be overwritten with the value specified by the user. The C variable is not modified if the user does not specify a value, so it is best to initialise it with an appropriate default value.

Sometimes it is necessary to perform some extra validation or initialisation when a variable is passed. For example, bugle-showstats(7) accepts the show variable multiple times to indicate which statistics should be displayed. The callback field may be set to a callback function, which is passed a pointer to the corresponding filter_set_variable_info object, the raw string present in the configuration file, and a pointer to the interpreted value. Note that at the time of the callback, the variable passed will not have been modified. The callback should return false if the value was invalid and true otherwise.

4.6.3. Filter-set initialisation and destruction

Apart from initialising internal structures, a filter-set loader registers filters and callbacks. The function to register a filter within a filter-set is

filter * bugle_filter_new(filter_set *handle, const char *name);

A filter * is an opaque handle to a filter. It is passed to the following functions to register callbacks:

void bugle_filter_catches(filter *f, const char *group, bool inactive, filter_callback callback);
void bugle_filter_catches_function(filter *f, const char *function, bool inactive, filter_callback callback);
void bugle_filter_catches_all(filter *f, bool inactive, filter_callback callback);

These respectively register callbacks for a single group, a single function, or all functions. The inactive says whether the callback should apply when the filter-set is inactive. Usually you will want to set this to false, but in some cases it is necessary to track some state even when the filter-set is inactive. When using a group, you can use the name of any function in that group, although it is best to use the one with the oldest name as bugle is most likely to know about it. If bugle was compiled without OpenGL headers exposing that function, it is ignored.

A filter-set should also indicate ordering dependencies between filters. This is done by calling

void bugle_filter_order(const char *first, const char *second);

This does not require that either filter is actually loaded. It simply indicates that if both are present, then they are to be run in the specified order. The most common use is to specify an ordering relative to invoke, the filter that is responsible for passing a function call on to the real OpenGL library.

4.6.4. Writing callbacks

In the functions above, callback is a function with the signature

bool callback(function_call *call, const callback_data *data);

The callback should generally return true. Returning false aborts any further processing of the call (including execution if the invoke filter has not yet run). This can be useful if you want to suppress a call, but if possible it is better to allow execution and undo the effects afterwards so that later filters get a chance to run.

Callbacks that handle multiple OpenGL functions will need to know which function was called; the function is found in call->generic.id, but more useful is the group found in call->generic.group. One can also get access to the arguments: if the call is known to be glFunction, then *call->glFunction.argi is the ith argument, and *call->glFunction.retn is the return value. If the function is not known at compile time, then the arguments can be accessed via the void pointers call->generic.args[i] and call->generic.retn. These values can also be modified to change the arguments used or the value returned to the application, respectively.

The data is currently still undergoing revision, so it will not be documented yet.

4.7. Object shadowing

Bugle has support for associating data with OpenGL objects such as contexts, textures, calls and so on. It is implemented using a generic interface that is not OpenGL-specific, and utility code to deal with specific types of objects is implemented on top of this.

4.7.1. Concepts

class (object_class)

A class is like an OOP class, in that objects are instantiations of classes with data.

registrant

Several units of code may wish to attach storage to an object, and they need to be kept separate from each other. Each such unit is known as a registrant. There is no explicit structure to represent registrants: it's just a piece of terminology for the documentation.

object (object *)

An object holds all the data that all registrants have attached to a single OpenGL object. It should be treated as being opaque.

view (object_view)

This term is somewhat ambiguous. The object_view type is a key used to fetch a particular registrant's data from objects of a particular class. In some places, however, it also means the actual data that is stored in the object.

Each registrant is free to define these data in any way it likes. The memory will be suitably aligned for all built-in data types (at present the memory is allocated with malloc, but this may well change for efficiency reasons).

scope

This has nothing to do with inheritence. It refers to the scope at which an object can be considered to be current. For example, each thread has a current context, and each context may have a current display list, so display lists have context scope. Bugle allows you so specify what the current object for each class is (which may be NULL), and retrieve it later.

4.7.2. Class management functions

Class structs are generally declared as global pointers with external linkage, so that code that uses them may access them directly.

#include <bugle/objects.h>
                    
object_class *bugle_object_class_new(object_class *parent);
void bugle_object_class_free(object_class *klass);

These are the constructor and destructor for classes. The parent is either the class defining the scope of the new class, or NULL to indicate that the new class has thread scope (like an OpenGL context).

Warning

The bugle_object_class_free function does not delete instances of the class. They must be manually deleted first. Attempting to manipulate objects once their class (or any ancestor class in the scope tree) has been deleted will lead to undefined behaviour.

object_view bugle_object_view_new(object_class *klass, 
                                       void (*constructor)(const void *, void *), 
                                       void (*destructor)(void *), 
                                       size_t size)

This function creates a new view on an existing class. The constructor is described later. The destructor is simply called when the object goes away, and receives a pointer to the view data. It is responsible for cleaning up, but it must not attempt to free the pointer.

The size is the number of bytes that the registrant wishes to associate with each instance of this class. It is legal for the size to be zero, in which case no data is associated but the constructor and destructor will still be called to provide notification of object creation and destruction.

4.7.3. Object management functions

Since the object system has no knowledge of OpenGL, each type of object requires some management code to shadow creation and destruction of OpenGL objects, and to keep track of which object is current.

object *bugle_object_new(object_class *klass, const void *key, bool make_current);

This instantiates a new instance of the given class. Instantiate an instance of the given class. Firstly, if make_current is true then the new object is immediately made the current object of its class. Then, for each registrant the constructor is called to initialise the data in its view. The constructor is passed key and the view data (the key parameter exists only to pass extra information to the constructor, usually about the associated GL object). Before calling the constructor, the view data is filled with zero bytes. The constructor is optional and may be NULL.

void bugle_object_free(object *obj);

For each registrant of the class, calls the destructor (if any), passing a pointer to the view data. It then frees the memory associated with the object. Don't forget that some OpenGL objects don't actually die when you delete them, only when they are no longer referenced.

object *bugle_object_get_current(const object_class *klass);
void bugle_object_set_current(object_class *klass, object *obj);

These functions get and set the current object, within the context of that class. For example, when setting the current display list, it is made current within the current OpenGL context, and switching OpenGL contexts will yield a new current display list. It is legal for the current object to be NULL, and in fact this is the initial state.

If the current object is destroyed, then NULL becomes the new current object.

void *bugle_object_get_data(object *obj, object_view *view);
void *bugle_object_get_current_data(object_class *klass, object *obj);

This retrieves the view data stored in obj. The view is the handle returned by bugle_object_view_register. One can get the data from the current object with the convenience function bugle_object_get_current_data (if it is certain that the current object is not NULL).

4.7.4. Thread safety

Manipulations of a particular class must be serialised, as there is no internal protection against concurrent access. This is seldom a problem since modification of a class is usually done during startup and shutdown, which are serialised.

The object manipulation functions are safe to use concurrently, since the object structures are not modified. Setting the current object is thread-safe unless the class has a parent in the scope tree and an instance of that parent is current in more than one thread. Even then, it is safe on most reasonable machines, since setting the current object amounts to overwriting a single pointer. Note that bugle_object_new and bugle_object_free may both set the current object implicitly.

Manipulation of the view data is of course up to each individual registrant, and it is responsible for managing any concurrency issues that arise.

4.8. Utility functions and filter-sets

The functions listed above are the minimal set needed to write a filter-set. This section describes a number of utilities which simplify the job of writing a more powerful filter-set. Most of the functions described here are defined in bugle/gl/glutils.h.

4.8.1. Begin/end checking

Many OpenGL functions may not be called between glBegin and glEnd. To facilitate checking for this, the glbeginend filter-set provides the boolean function bugle_gl_in_begin_end which indicates whether the current context is in this state. This function is defined in the header bugle/gl/glbeginend.h. You must also also call bugle_gl_filter_post_queries_begin_end("filtername") as part of the filter-set initialisation, for filters that run after invocation. Failing to do so may yield incorrect results during interception of glBegin or glEnd.

Warning

Do not call bugle_gl_filter_post_queries_begin_end for filters that run before invocation, or you will generate a cyclic dependency.

If there is no current OpenGL context, this call will return true. This means that whenever the call returns false, it should be safe to issue OpenGL commands. Refer to Section 4.8.3, “Making calls to OpenGL” for more information about making OpenGL calls from within a filter-set.

4.8.2. Error checking

It is often useful to know whether an OpenGL call generated an OpenGL error. If your filter-set filterset wishes to do this, it must call bugle_gl_filter_set_queries_error("filterset") during library initialisation. To actually retrieve the error, call bugle_gl_call_get_error(data->call_object).

This mechanism is not totally reliable. It is illegal to call glGetError when there is no OpenGL context or when between glBegin and glEnd. In these cases, GL_NO_ERROR may be returned even though the call did not succeed.

In the current implementation, enabling this mechanism also drasticly reduces performance, as every function call is intercepted to call glGetError.

4.8.3. Making calls to OpenGL

If you attempt to call an OpenGL function directly, the interception system will intercept the call and bugle will be entered recursively. There is protection against this (the call will be forwarded to the real OpenGL library without further action), but it is nevertheless a performance hit. To call an OpenGL function glFunction, you should call it as

CALL(glFunction)(args);

This should only be done if you put the actual name of the function as literal text. If you have a string containing the name, it can be passed to budgie_function_address_real instead.

If glFunction was not known when bugle was compiled, this will generate a call to glFunction. If the OpenGL library does not have this symbol (which it need not, since OpenGL entry points beyond OpenGL 1.2 should be queried with glXGetProcAddressARB), then you will get an unresolved symbol error at run-time. On Windows, you will get a link failure.

If the function is not defined by OpenGL 1.1, you must first check that the extension is supported at run time, and if it is not defined by OpenGL 2.0, you must also check that it is defined at compile time. This is described in Section 4.8.4, “Checking for OpenGL extensions”. Note that bugle will first try the function whose name exactly matches what you pass, but if that does not exist, it will then try the other functions in the same group.

For OpenGL (as opposed to GLX) functions, it is also important to have a valid context which is not inside begin/end. Some utilities are provided to simplify the interaction with begin/end checking. A filter-set that wishes to make OpenGL calls must be registered at library initialisation time with

bugle_gl_filter_set_renders("filter-set");

and any filters that make such calls and which run after invocation must be registered during filter-set initialisation with

bugle_gl_filter_post_renders("filter");

To begin a section of code that wishes to make OpenGL function calls, call bugle_gl_begin_internal_render(). It will return a boolean, indicating whether it is safe to proceed. If it is, you must terminate that block of code by calling bugle_gl_end_internal_render("name", true); The first parameter is a descriptive name for the section of code (typically the name of the containing function), which is logged if the code generates any OpenGL errors. Setting the second parameter to false, however, suppresses the warning, which should only be done if you have intentionally written code that may generate OpenGL errors.

4.8.4. Checking for OpenGL extensions

Like functions and groups, bugle enumerates the extensions it knows about, but the enumeration may change frequently and so is not part of the API. Mapping between names and the enumeration can be done with bugle_gl_extension_name and bugle_gl_extension_id, and the macro BUGLE_GL_EXTENSION_ID can be used with the literal unquoted name of the extension.

The following macros simplify checking for the presence of an OpenGL extension in the current context:

#include <bugle/gl/glextensions.h>

bool BUGLE_GL_HAS_EXTENSION(GL_EXT_some_extension);
bool BUGLE_GL_HAS_EXTENSION_GROUP(GL_EXT_some_extension);

bugle_filter_set_depends("myfilterset", "glextensions");

An extension group is a set of extensions with similar functionality. For example, when passing GL_EXT_pixel_buffer_object to BUGLE_GL_HAS_EXTENSION_GROUP, it will return true if any one of GL_EXT_pixel_buffer_object, GL_ARB_pixel_buffer_object, or OpenGL 2.1 is available.

Note

Unlike with function groups, there associations are not usually symmetric, because extensions supersede others rather than having identical functionality.

There are also some special extension groups, defined in gengl/gengl.perl, that are convenient ways to test for certain functionality that is provided by several extensions but is not the sole function of any of them.

Apart from extensions, you can also check for OpenGL versions using symbols such as GL_VERSION_2_0. The list of extensions is parsed once per context, so these checks are reasonably cheap. If there is no current context, the function returns false.

Remember that you also need to do a compile-time check before using any of these symbols; see Section 4.3.3, “OpenGL extensions” for details.

Chapter 5. Hacking bugle

5.1. Porting

5.1.1. Introduction

Wherever possible, autoconf, libtool and gnulib are used to hide the gory details of porting to different operating systems. However, because bugle interfaces directly into the host system in a number of ways, some work is required to port bugle to new systems.

While other projects may have simply a Windows port and a GNU port, for example, but it is not so simple for bugle. For example, one might run on Windows but using Cygwin with an X server, or on Linux but using EGL rather than GLX. Instead, a target system is based on a number of categories:

Binary format

The binary format determines the details of how dynamic linking is done and how it may be subverted. For example, the Windows PE format explicitly indicates which symbols come from which library, and hence require an entire library to be impersonated, while ELF files just list dependent libraries and dependent symbols, making it easy to replace certain symbols.

Operating system API

This determines how things like segfault handling and other low-level operations are performed. Examples are POSIX and Win32.

Windowing system

The main effect of the windowing system is to determine how keyboard and mouse events may be intercepted.

GL-Window system integration

This determines how GL interacts with the windowing system. Usually there is a one-to-one mapping (e.g., AGL, WGL, GLX), but EGL applies on any windowing system.

Filesystem layout

This determines where to look for files, namely bugle configuration files and system libraries, and potentially temporary files.

Rather than conditionally compiling code based on the particular system in use, each system is characterised by a set of defines that describe its essential properties. This makes it easier to port bugle to similar but not identical systems in future: new code is needed only for those parts either specific to the system in question, or where the new system behaves in an entirely novel way.

5.1.2. Binary format

The following properties are defined as either 0 or 1, meaning false or true; the descriptions indicate the meaning if true:

BUGLE_BINFMT_SYMBOL_BY_DSO

The binary format lists the external library that is to be used for each external symbol.

BUGLE_BINFMT_LDPRELOAD

Bugle is injected by LD_PRELOAD or an equivalent mechanism. If false, the bugle library is given the same name as the usual OpenGL library (e.g., opengl32.dll on Windows), and loads the original library with a full path.

At present the supported binary formats are PE (BUGLE_BINFMT_PE) and ELF (BUGLE_BINFMT_ELF), although other formats could well be similar enough to be put in the same category.

5.1.3. Operating system API

For the most part, code that needs to be OS API aware needs to have code implemented for each target OS. The only use of this in the API at present is the use of signal and siglongjmp to return useful information in the face of an access violation, and these functions may be detected via autoconf.

For this reason, no preprocessor symbols are currently defined to indicate the OS API. This is subject to change should a need arise.

5.1.4. Windowing system

As for OS porting, code that is windowing system specific needs to be written for each windowing system. The following window systems are defined:

  • BUGLE_WINSYS_X11

  • BUGLE_WINSYS_WINDOWS

5.1.5. GL-Windowing integration

The primary difference between GL-Windowing integration APIs is whether extension function pointers are context-dependent or constant. This is determined by BUGLE_GLWIN_CONTEXT_DEPENDENT. The only currently supported instance of this is WGL (BUGLE_GLWIN_WGL). EGL (BUGLE_GLWIN_EGL) and GLX (BUGLE_GLWIN_GLX) both require function pointers to be the same in any context.

5.1.6. Filesystem layout

Filesystem layout determines the conventional placement of files. Three variants are defined

BUGLE_FS_UNIX

Configuration files are stored in $HOME/.bugle and system libraries are searched for in /usr/lib.

BUGLE_FS_CYGMING

Configuration files are stored in $HOME/.bugle, but system libraries are searched for in GetSystemDir().

Appendix A. Bugle debugger protocol

A.1. Introduction

The debugger component of bugle uses a wire protocol to communicate data between the debugger filter-set and the debugger application. The protocol is documented here.

It should be noted that this protocol has many shortcomings:

  • It is unversioned, so the endpoints may be using different versions of the protocol and not be aware of this until something goes catastrophically wrong.

  • It is not endian-safe. While the control codes this is easily fixed for the control codes, there is little point in doing so until the data being transferred can be placed into a canonical representation.

  • It may in places be dependent on the pointer size of the system, in particular when transferring GL pointer state.

  • Packets do not contain a length field, making it impossible to skip unknown packets.

In spite of these limitations, it has been successively used to debug an OpenGL ES application running on an ARM CPU with the debugger running on top of OpenGL on a 64-bit Intel CPU.

The goal is to eventually address these limitations, and patches are welcomed.

A.2. Basics

The protocol is a binary packet-based protocol. The debugger makes requests to the filter-set, which returns responses. Packets have identifiers to facilitate pipelining. In addition, there are certain responses that may be generated asynchronously by the filter-set.

A.2.1. Types

NameDescription
UINT3232-bit big-endian unsigned integer
INT3232-bit twos-complement big-endian signed integer
CODEsame as UINT32, but for debugger protocol enumerated values
GLENUMsame as UINT32, but for OpenGL enumerated values
BOOLA UINT32 with the value 1 (true) or 0 (false)
STRINGA length (as UINT32) followed by that number of bytes. The character set is UTF-8, in most cases it will be plain ASCII.
BLOBA piece of binary data, encoded in the same way as STRING

A.2.2. States

Over the lifetime of the debugged process, it will move between three states. When it first starts, it is in the startup state, and waits for instructions from the debugger. At this point, the debugger will send breakpoints and other requests that need to be in place before the program starts issuing GL commands. Once the REQ_RUN request is received, the program enters the running state. From this point, it will alternate between running and stopped. The filter-set will accept commands in both states (although if no GL commands are issued, the filter will not run and so will not be responsive). However, in the stopped state, the filter-set will block and wait for commands and will prevent the thread it is in from running, while in the running state, it will only process commands that are available[1] and will allow its thread to continue running normally.

A.3. Requests

These are the requests that the debugger may make to the filter-set. The values for CODE fields are listed symbolically; the symbol values can be found in common/protocol.h.

Each request starts with the request type and a request ID. Request IDs are arbitrary values chosen by the debugger to identify requests. Responses include the request ID, to facilitate matching of responses to requests. Request IDs need not be unique.

A.3.1. Run

Starts the program running. Once it is running, the response RESP_RUNNING is returned, ahead of any asynchronous response that might result.

TypeDescription
CODEREQ_RUN
UINT32request ID

A.3.2. Continue

Continue running a stopped program.

TypeDescription
CODEREQ_CONT
UINT32request ID

A.3.3. Step

Continue running, but break on the next call.

TypeDescription
CODEREQ_STEP
UINT32request ID

A.3.4. Break on function

Set or clear a breakpoint on a function.

TypeDescription
CODEREQ_BREAK
UINT32request ID
STRINGname of the function
BOOLtrue to set, false to clear

A.3.5. Break on event

Set or clear a breakpoint on an event class.

TypeDescription
CODEREQ_BREAK_EVENT
UINT32Request ID
CODE

one of

  • REQ_EVENT_GL_ERROR: error from glGetError
  • REQ_EVENT_COMPILE_ERROR: failed shader compilation
  • REQ_EVENT_LINK_ERROR: failed shader link
BOOLtrue to set, false to clear

A.3.6. Break on error

This is an obsolete command, equivalent to REQ_BREAK_EVENT with an event type of REQ_EVENT_GL_ERROR.

TypeDescription
CODEREQ_BREAK_ERROR
UINT32request ID
BOOLtrue to set, false to clear

A.3.7. Stop

Requests a running program to stop at the next available point. It is ignored if the program is already stopped when the command is received.

TypeDescription
CODEREQ_ASYNC
UINT32request ID

A.3.8. Quit

Requests the program to terminate.

TypeDescription
CODEREQ_QUIT
UINT32request ID

A.3.9. Filter-set activation and deactivation

Filter-sets can be enabled or disabled on the fly by the debugger, similarly to the way they can be activated or deactivated using key sequences.

TypeDescription
CODEREQ_ACTIVATE_FILTERSET or REQ_DEACTIVATE_FILTERSET
UINT32request ID
STRINGname of the filter-set

A.3.10. State requests

Requests a readout of all the GL state.

TypeDescription
CODEREQ_STATE_TREE_RAW
UINT32request ID

State can also be requested in a text form, but this is deprecated:

TypeDescription
CODEREQ_STATE_TREE
UINT32request ID

A.3.11. Data requests

Request data from a GL object. This command has a common header, and a number of possible sub-types.

A.3.11.1. Texture data

TypeDescription
CODEREQ_DATA
UINT32request ID
CODEREQ_DATA_TEXTURE
UINT32GL name of the texture object
GLENUMtexture target
GLENUMtexture face (used only for cubemaps, otherwise ignored)
UINT32texture level
GLENUMformat parameter to glGetTexImage
GLENUMtype parameter to glGetTexImage

A.3.11.2. Framebuffer data

TypeDescription
CODEREQ_DATA
UINT32request ID
CODEREQ_DATA_FRAMEBUFFER
UINT32GL name of the framebuffer object (zero for the window-system framebuffer)
GLENUMframebuffer target (currently ignored but should be GL_FRAMEBUFFER)
GLENUMread buffer
GLENUMformat parameter to glReadPixels
GLENUMtype parameter to glReadPixels

A.3.11.3. Shader source

TypeDescription
CODEREQ_DATA
UINT32request ID
CODEREQ_DATA_SHADER
UINT32GL name of the shader object (either GLSL or ARB shader)
GLENUMshader type (GLSL) or target (ARB shader)

A.3.11.4. Info log

This is used for shader or program info log of a GLSL shader. It is valid to query for ARB programs, but the info log is always empty.

TypeDescription
CODEREQ_DATA
UINT32request ID
CODEREQ_DATA_INFO_LOG
UINT32GL name of the shader or program object
GLENUMshader type, or GL_PROGRAM_OBJECT_ARB for GLSL programs (even in OpenGL ES, where is not a defined enum)

A.3.11.5. Buffer

This query returns the contents of a buffer (VBO).

TypeDescription
CODEREQ_DATA
UINT32request ID
CODEREQ_DATA_BUFFER
UINT32GL name of the shader or program object

A.4. Synchronous responses

Synchronous responses are replies to requests. Each synchronous response start with a response type and the request ID of the request it is in response to. Responses are always returned in the same order as the requests were received, but may potentially be intermixed with asynchronous responses.

A.4.1. Error

This is a general-purpose error response to any request which failed. The error code is currently unused and will always be zero. It is reserved for future use, where defined error codes may facilitate automatic interpretation of the error.

TypeDescription
CODERESP_ERROR
UINT32request ID
CODEerror code
STRINGhuman-readable error message

A.4.2. Answer

This is a general-purpose successful answer response. The meaning of the value field is determined by the corresponding request. Currently, no requests use this field and its value is undefined.

TypeDescription
CODERESP_ANS
UINT32request ID
UINT32value

A.4.3. Running

This is sent in response to REQ_RUN, to indicate that the debugger has successfully initialised.

TypeDescription
CODERESP_ERROR
UINT32request ID

A.4.4. Binary state dumps

The GL state is returned as a contiguous block of responses, with no intermediate asynchronous responses. Each node in the tree is encoded as a RESP_STATE_NODE_BEGIN_RAW (which contains information about the root of the tree, if any), then the children encoded recursively, then a RESP_STATE_NODE_END_RAW response to indicate the end of the children. The same request ID is used for the whole set of responses.

A.4.4.1. Begin response

TypeDescription
CODERESP_STATE_NODE_BEGIN_RAW
UINT32request ID
STRINGname of the state (empty for the root state)
UINT32numeric name of the state, which is state dependent (typically it is a GL name)
GLENUMenum name of the state, which is state dependent (typically it is a pname parameter to a GL query function)
STRINGthe mangled type name, as returned by budgie_type_name
INT32element count for an array, −1 for a non-array, and −2 if an error occurred in trying to retrieve the value
BLOBthe value of the state (currently using host object representation)

A.4.4.2. End response

TypeDescription
CODERESP_STATE_NODE_END_RAW
UINT32request ID

A.4.5. Textual state dumps

Textual state dumps work similarly to binary state dumps, except that the state is formatting into a human-readable string by the filter-set. It is recommended that clients do not attempt to parse these strings, and should instead use a binary state dump if they intend to inspect values.

A.4.5.1. Begin response

TypeDescription
CODERESP_STATE_NODE_BEGIN
UINT32request ID
STRINGname of the state (empty for the root state)
UINT32numeric name of the state, which is state dependent (typically it is a GL name)
GLENUMenum name of the state, which is state dependent (typically it is a pname parameter to a GL query function)
STRINGthe human-readable value of the state

A.4.5.2. End response

TypeDescription
CODERESP_STATE_NODE_END
UINT32request ID

A.4.6. Data responses

The response to data requests varies by the sub-type of the request. In each case, the data is returned as a binary blob, exactly as it was returned by the appropriate GL query function. The client pixel pack state is set to the default, except that GL_PIXEL_PACK_ALIGNMENT is set to 1.

A.4.6.1. Texture data response

TypeDescription
CODERESP_DATA
UINT32request ID
CODEREQ_DATA_TEXTURE
BLOBtexture data
UINT32width
UINT32height (1 for 1D textures)
UINT32depth (1 for 1D and 2D textures)

A.4.6.2. Framebuffer data response

TypeDescription
CODERESP_DATA
UINT32request ID
CODEREQ_DATA_FRAMEBUFFER
BLOBframebuffer data
UINT32width
UINT32height (1 for 1D textures)

A.4.6.3. Shader source response

TypeDescription
CODERESP_DATA
UINT32request ID
CODEREQ_DATA_SHADER
STRINGshader source

A.4.6.4. Info log response

TypeDescription
CODERESP_DATA
UINT32request ID
CODEREQ_DATA_INFO_LOG
STRINGinfo log

A.4.6.5. Info log response

TypeDescription
CODERESP_DATA
UINT32request ID
CODEREQ_DATA_BUFFER
BLOBbuffer data

A.5. Asynchronous responses

Asynchronous responses are generated when the program transitions from running state to stopped state. Except where otherwise noted, they can occur any time the program is running, potentially interleaved with synchronous responses.

Asynchronous responses include a request ID field, which contains the request ID of the last request that started the program running.

A.5.1. Break

This response is sent when the program is stopped just before executing a function call. This can be due to a user breakpoint on the function, or reaching the next function after a REQ_STEP or REQ_ASYNC.

TypeDescription
CODERESP_BREAK
UINT32request ID
STRINGdescription of the function call

A.5.2. Break on event

This response is used when the program is stopped just after executing a function call, as a result of something that occurred in the debugged application (such as a GL error).

TypeDescription
CODERESP_BREAK_EVENT
UINT32request ID
STRINGdescription of the function call
STRINGdescription of the event

A.6. Protocol definition

The previous sectiosn describe the individual request and response packets. Here we describe their relationship to each other and the transitions between states in the system.

The intention is that except where otherwise noted, illegal requests should result in an error being returned. However, this is not fully implemented and you should not depend on this.

The table below shows the valid states for each command, the resulting state on success (empty meaning no change), and the expected non-error, synchronous response.

RequestOld stateNew stateResponse
REQ_RUNstartuprunningRESP_RUNNING
REQ_CONTstoppedrunningnone
REQ_STEP
REQ_BREAKany RESP_ANS
REQ_BREAK_EVENT
REQ_BREAK_ERROR
REQ_STOPstopped, runningstoppednone
REQ_QUITstopped, runningdeadnone (process exits)
REQ_ACTIVATE_FILTERSETstopped, running RESP_ANS
REQ_DEACTIVATE_FILTERSET
REQ_STATE_TREE_RAWstopped, running sequence of RESP_STATE_NODE_BEGIN_RAW and RESP_STATE_NODE_END_RAW
REQ_STATE_TREEsequence of RESP_STATE_NODE_BEGIN and RESP_STATE_NODE_END
REQ_DATAstopped, running RESP_DATA (with matching subtype)


[1] Actually, as long as there is data available on the connection, it will consume a complete command. Thus, sending a partial command and stopping will cause a stoppage. This should probably be fixed.

Appendix B. FAQ

B.1. Compiling

Q: How do I build a 32-bit version of bugle on an AMD64 system?
Q: Why is a recent (>3.0) version of GCC required?
Q: Why I am getting an error like Invalid option -fdump-translation-unit?
Q: I get an error trying to move gl.c.tu, saying that the file does not exist.
Q: When I compile with GCC 4.2, compilation seems to hang on src/lib.c.
Q: I am getting the error could not find GL/glext.h.
Q: I am using the NVIDIA header files, and I am getting errors about conflicting definitions.
Q: I am using Gentoo, and during compilation of bugle I get errors similar to this: /usr/lib/opengl/nvidia/lib/libGLcore.so.1: undefined reference to `_nv000016gl'.
Q: I have an x86-64 (Athlon 64/Opteron/EM64T) machine with 64-bit OS, and compilation fails with the message /usr/lib/libGL.so: could not read symbols: File in wrong format.
Q: I am using Fedora 10, and when I run glxgears under bugle it exits with the message Error: couldn't get an RGB, Double-buffered visual.
Q: Why do I get the error *** %n in writable segment detected ***?

Q:

How do I build a 32-bit version of bugle on an AMD64 system?

A:

The exact details will depend on your OS. Here is what I do on Gentoo:

$ ./configure --x-libraries=/usr/lib32 CC="gcc -m32" CXX="g++ -m32" \
    --libdir=/usr/local/lib32 --bindir=/usr/local/bin32

Gentoo also tries to be clever by putting in a libGL.la to make linking against OpenGL work better, but in some cases it causes libtool to pick up the 64-bit version of OpenGL. I work around this by copying /usr/lib/libGL.la into the compilation directory, and replacing all references to /usr/lib with /usr/lib32.

Q:

Why is a recent (>3.0) version of GCC required?

A:

Bugle is driven by a number of tables that list all the information about the various types and functions in OpenGL. To capture this information, it is necessary to parse the OpenGL header files. It would be very difficult to write a parser to do this robustly, but GCC already knows how to do this. Unfortunately, the ability to extract a parse tree from GCC (the -fdump-translation-unit option) was only added sometime after 3.0, and is also broken in 4.0 (fixed in 4.1).

Q:

Why I am getting an error like Invalid option -fdump-translation-unit?

A:

You need to use a version of GCC that supports this flag. See the previous question for details.

Q:

I get an error trying to move gl.c.tu, saying that the file does not exist.

A:

You are probably using GCC 4.0, which has broken support for -fdump-translation-unit (GCC bug 18279). Use GCC 3.x or 4.1 instead.

Q:

When I compile with GCC 4.2, compilation seems to hang on src/lib.c.

A:

There is a performance bug in GCC 4.2.2, possibly #30052 but possibly not. Either downgrade to 4.1, upgrade to a version where the bug is fixed , or compile without optimisation (-O0).

Q:

I am getting the error could not find GL/glext.h.

A:

You need to have this file, as it defines extensions to OpenGL that an application might use. You can obtain the latest copy from http://www.opengl.org/registry. If you don't want to put it in your system include directories, you can create a GL subdirectory of the bugle source directory and put it there.

Q:

I am using the NVIDIA header files, and I am getting errors about conflicting definitions.

A:

Try upgrading to the latest NVIDIA drivers. The 60 series seem to fix many of the problems in older header files.

Alternatively, use the headers from Mesa. You can place them into a GL subdirectory of the source if you prefer not to overwrite the system headers.

Q:

I am using Gentoo, and during compilation of bugle I get errors similar to this: /usr/lib/opengl/nvidia/lib/libGLcore.so.1: undefined reference to `_nv000016gl'.

A:

This seems to be a problem with Gentoo's system for switching between OpenGL drivers, that causes part of the build process to use the X11 software drivers. A workaround is to switch to the X11 drivers for compilation and installation of bugle:

  1. Run eselect opengl set xorg-x11 (or opengl-update xorg-x11 on older systems) as root.

  2. Ensure that your environment is up to date e.g., source /etc/profile in the shell you will use to compile bugle.

  3. Unpack a fresh copy of bugle (do not use a previously configured copy), compile and install it.

  4. Switch back to the NVIDIA OpenGL driver (eselect opengl set nvidia).

Q:

I have an x86-64 (Athlon 64/Opteron/EM64T) machine with 64-bit OS, and compilation fails with the message /usr/lib/libGL.so: could not read symbols: File in wrong format.

A:

This has been reported on Fedora Core 5, where libtool incorrectly tries to link against the 32-bit version of libGL.so. The workaround is to run (in the build directory)

sed -i 's#sys_lib_search_path_spec="#sys_lib_search_path_spec="/usr/lib64#' libtool

and re-run make. If this still doesn't work, see if your 64-bit libGL.so is in a different directory and use that in place of /usr/lib64 above.

Q:

I am using Fedora 10, and when I run glxgears under bugle it exits with the message Error: couldn't get an RGB, Double-buffered visual.

A:

This seems to be caused by having two different versions of libGL.so on your system, and bugle picking up symbols from the wrong one. Find out which one is correct (ldd) should help, then move other ones out of the way.

Q:

Why do I get the error *** %n in writable segment detected ***?

A:

Most likely your distribution has crippled GCC by switching on options that improve security but are not C compliant. Try adding -U_FORTIFY_SOURCE to your CFLAGS.

B.2. Running

Q: What is the performance penalty?
Q: I wrote LD_PRELOAD=libbugle.so program and it failed, what's up?
Q: How do I get a stack trace when my program crashes inside the OpenGL driver?
Q: Do I need to always set BUGLE_CHAIN?
Q: Can I avoid using LD_PRELOAD?
Q: How do you get SDL-based apps to use BuGLe?
Q: How do you get Quake3 or Doom3 to use BuGLe?
Q: How do you get QT-based apps to use BuGLe?
Q: I am using GL_EXT_framebuffer_object to render to texture, but the results do not appear in the texture viewer of gldb-gui.
Q: I'm running 64-bit bugle on a 64-bit OS with a 64-bit application, but when I try to run it, it tries to open the 32-bit version of libGL.so.
Q: I am using ATI drivers and when I run configure, it does not find glBegin in -lGL.

Q:

What is the performance penalty?

A:

That depends on what you're doing with the library. If you only use filter-sets that intercept a few functions (like showstats), then all other functions suffer only a small penalty. Using filter-sets that check for error after every function (including showerror and the debugger) adds a much bigger penalty.

To give you an example, here are some rough numbers for Quake3 1.32c on demo four:

without bugle683.7
none668.4
logfps661.8
showfps625.6
trace181.6
gldb-gui131.3

Tracing is particularly slow because it does file I/O, as well as a lot of text formatting. The overhead will also depend on the CPU/GPU balance. GPU-bound programs will be less affected by overheads.

Q:

I wrote LD_PRELOAD=libbugle.so program and it failed, what's up?

A:

You either need to specify a full path to libbugle.so, or else place it somewhere that the linker will find. On GNU systems, you can add the appropriate path to /etc/ld.so.conf.

Q:

How do I get a stack trace when my program crashes inside the OpenGL driver?

A:

Use the bugle-unwindstack(7) filter-set. See the manual page for more information.

A:

Use the bugle-log(7) filter-set, and turn on the flush option (see the example in doc/examples/filters). Then after your program crashes, the last entry in the log file will most likely be the one just before the crash.

Q:

Do I need to always set BUGLE_CHAIN?

A:

No, the first chain in the configuration file is the default.

Q:

Can I avoid using LD_PRELOAD?

A:

Yes, you can specify -lbugle in place of -lGL when you link your program. If it is not installed in a standard directory, you may need extra compiler flags, such as -L/path/to/bugle -Wl,-rpath -Wl,/path/to/bugle.

Q:

How do you get SDL-based apps to use BuGLe?

A:

On GNU systems, they should work as is. On some systems, it may be necessary to run them as

LD_PRELOAD=/path/to/libbugle.so SDL_VIDEO_GL_DRIVER=/path/to/libbugle.so program

Q:

How do you get Quake3 or Doom3 to use BuGLe?

A:

On GNU systems, they should work as is. On some systems, run it as

LD_PRELOAD=/path/to/libbugle.so quake3 +set r_glDriver /path/to/libbugle.so

Note that Quake3 and Doom3 are 32-bit binaries, so if you have an AMD64 system you will need to compile a 32-bit bugle.

Q:

How do you get QT-based apps to use BuGLe?

A:

On GNU systems, they should work as is. There is currently no known workaround for systems that don't support dlsym with the RTLD_NEXT flag.

Q:

I am using GL_EXT_framebuffer_object to render to texture, but the results do not appear in the texture viewer of gldb-gui.

A:

This is a known bug in NVIDIA's 76.76 driver. It is fixed in the 80 series drivers. The results should appear in the framebuffer viewer.

Q:

I'm running 64-bit bugle on a 64-bit OS with a 64-bit application, but when I try to run it, it tries to open the 32-bit version of libGL.so.

A:

I haven't heard if this actually works, but try setting LTDL_LIBRARY_PATH to the path containing your 64-bit OpenGL library (probably /usr/lib64. If you run into this problem, please let me know if this workaround is effective.

A:

Another potential workaround is to replace libGL.so in gl.bc.in with the full path before running configure. Again, please let me know whether this is effective.

Q:

I am using ATI drivers and when I run configure, it does not find glBegin in -lGL.

A:

I have had this reported by one Debian user, but didn't get further details on hardware or driver version. It appears that this version depended on but did not link to libpthread. While it is possible to hack this in configure.ac, the same user reported other problems with this driver, and it is probably best to upgrade to a newer driver.

B.3. Miscellaneous

Q: Why is there a mix of C and C++ code?

Q:

Why is there a mix of C and C++ code?

A:

The library itself is written entirely in C. This is mainly because a C++ library will drag libstdc++ in with it, and this has been found to create some problems when forcing linking to an application that already depends on a conflicting version of libstdc++. There is still a dependence on libc, but libc is less of a moving target. The code generator is written in C++, since it makes the coding easier and does not introduce the dependency issues above.

Appendix C. Bugle manual pages

Table of Contents

bugle — An OpenGL debugging library
bugle-statistics — specify formulae and metadata for bugle statistics
gldb-gui — graphical OpenGL debugger
gldb — console-based OpenGL debugger
bugle-camera — allow the camera to be manipulated
bugle-checks — check for errors that OpenGL defines as undefined behaviour
bugle-eps — captures vector graphics representatios of scenes
bugle-error — detect errors in OpenGL calls
bugle-exe — record a compilable log of OpenGL calls made
bugle-extoverride — hide OpenGL extensions from an application
bugle-frontbuffer — force rendering to the front buffer
bugle-log — configure logging output from other filter-sets
bugle-logstats — log statistics to file
bugle-screenshot — takes screenshots and captures video
bugle-showerror — reports errors in OpenGL calls
bugle-showextensions — show which extensions are used by an OpenGL application
bugle-showstats — render statistics over the display
bugle-stats_basic — gather frame rate statistics
bugle-stats_calls — gather call frequency count
bugle-stats_calltimes — gather call timing
bugle-stats_fragments — gather fragment counts
bugle-stats_nv — gather performance data from NVPerfSDK
bugle-stats_primitives — gather triangle and batch counts
bugle-trace — record a log of OpenGL calls made
bugle-unwindstack — recover a stack trace after a segmentation fault
bugle-wireframe — force rendering in wireframe mode

Name

bugle — An OpenGL debugging library

Synopsis

BUGLE_CHAIN=chain LD_PRELOAD=libbugle.so program [argument...]

Description

bugle is a library that intercepts calls to OpenGL functions, in much the same way that many memory debuggers do. Calls are run through a number of user-specified filter-sets, including one that invokes the original call.

In addition, gldb-gui(1) allows an OpenGL application to be debugged by detecting OpenGL errors and showing OpenGL state. For common usage this may be the most convenient way to use bugle.

The BUGLE_CHAIN environment variable specifies a filter-set chain, which is simply a collection of filter-sets with options. Chains are defined in the configuration file, $HOME/.bugle/filters (see the section called “Configuration”).

Configuration

You can create filter-set chains in the file $HOME/.bugle/filters. It is possible to use bugle without creating this file, but it will simply pass all calls straight through to the real OpenGL library. This is not particularly useful unless you are using gldb-gui(1). A sample file is available in doc/examples/filters in the source distribution.

The file is text-based. Comments begin with a # and continue to the end of the line. Strings should be quoted with double-quotes, and backslash acts as an escape character in the usual way (including escaping of newlines). Other white-space is ignored. Each chain is specified as

chain chain
{
    filter-set
    filter-set
    filter-set
    ...
}

Filter-sets are specified as

filterset filterset [key [inactive]]
{
    option value
    option value
    option value
    ...
}

The key may be used to toggle the filter-set at run-time (not all filter-sets support this yet, and those that do will not always work). Key names are based on X KeySyms (see <X11/keysymdefs.h> for a list). They may also be prefixed with C-, A- or S- to indicate that the key must be combined with Ctrl, Alt or Shift respectively. Some filter-sets have options which are keys; these take the same format.

If you don't need to specify any options, it is also legal to omit the braces. Boolean options may be specified as yes/no, as true/false or as 1/0.

Filter-sets

Each filter-set is documented in its own manual page e.g., the trace filter-set is documented in bugle-trace(7). You can get a brief list of available filter-sets and their options by specifying an undefined chain e.g.,

$ BUGLE_CHAIN=help LD_PRELOAD=libbugle.so glxgears

Environment

BUGLE_CHAIN

Specifies the filter-set chain to use. If absent, the first chain in the configuration file is used.

BUGLE_FILTERS

If set, specifies an alternative configuration file to use instead of $HOME/.bugle/filters.

BUGLE_FILTER_DIR

If set, specifies an alternative directory in which to find modules. This option is currently used by the test suite, and is not intended for general use.

LD_PRELOAD

Tells the linker to load bugle.

BUGLE_DEBUGGER, BUGLE_DEBUGGER_HOST, BUGLE_DEBUGGER_PORT

Configuration for remote TCP/IP debugging. Refer to gldb-gui(1) for details.

Files

$HOME/.bugle/filters

Lists the possible filter-set chains. See the section called “Configuration” for a description of the format.

$HOME/.bugle/statistics

Definitions of statistics; see bugle-statistics(5) for more information.

Bugs

  • OpenGL color-index mode is not well supported.

  • Multi-threaded applications that call the GL from more than one thread will break in various ways. The debugger filter-set is particularly fragile.

  • Display lists may cause things to go wrong, depending on how they are created and what calls go into them.

See the pages for individual filter-sets for specific bugs affecting each.

Author

bugle is written and maintained by Bruce Merry.


Name

bugle-statistics — specify formulae and metadata for bugle statistics

Synopsis

"name" = expression
{
    precision 1
    label "label"
    max 100
}

Description

By default, bugle(3) gets statistics from ~/.bugle/statistics, although an alternative location may be specified in the BUGLE_STATISTICS environment variable. Most users will just copy the sample file doc/examples/statistics from the source distribution. This manual page describes the format in more detail for those who want to set up custom statistics.

In order to understand bugle's statistics system, one must first understand how it uses signals and statistics.

signals

A signal is a raw count of something, like number of frames, memory use, or load. For events, these are usually the total number of that event (like frame changes), rather than a rate. Signals are produced by generator filter-sets like bugle-stats_basic(7) or bugle-stats_primitives(7).

statistics

Statistics are high-level information computed from signals. For example, frame rate is computed from the number of frames signal and the time signal. Statistics also contain some metadata, such as the label to display with the statistic, and the number of significant digits to print. Logging filter-sets (bugle-logstats(7) and bugle-showstats(7)) use this information to display the statistics.

The statistics file contains the formulae used to compute statistics from signals, as well as the metadata mentioned above.

Syntax

Blank lines and lines beginning with a # are ignored. Statistics have the basic format shown in the synopsis. The expression consists of standard arithmetic operations (including parentheses), numbers, and signal expressions. When a signal expression is evaluated, it is done so over some interval of time (usually one frame), but key_accumulate in bugle-showstats(7) allows for longer intervals). Several types of signal expressions are available to determine how the signal is measured over that time:

d("signal")

measures the change in the signal over the interval

a("signal")

measures the average value of the signal during the interval

s("signal")

measures the value at the start of the interval

e("signal")

measures the value at the end of the interval

For measuring rates, use the ratio of two d expressions. For example, the default configuration defines the frame rate as

"frames per second" = d("frames") / d("seconds")
{
    precision 1
    label "fps"
}

For statistics not defined by rates (such as memory consumption), an a expression is generally sufficient.

Expressions are evaluated using floating-point arithmetic, applying the usual rules of operator precedence. If an expression evaluates to a non-finite value (infinity or NaN) it will not be shown at all. A non-obvious application this is that given two expressions E and F, the compound expression E / E * F means F unless E is zero.

The lines between the { and } contain metadata. The metadata keywords are:

precision digits

the number of digits to show after the decimal point

label "text"

the text to show with the statistic when logging

max number

a maximum value for the statistic, used to scale graphs to the correct height

substitute number "label"

causes label to be used as the value if the numerical value was number

Wildcards

A * may be used in the name of a signal. If the expression for a statistic contains any wildcards, it is a wildcard statistic. When a wildcard statistic is selected for logging, it is instantiated zero or more times, with every possible replacement for the wildcard which yields a valid expression (in the sense that all the resulting signals must exist). If * appears several times in the expression, all occurrences are replaced with the same value in each instance.

In order to differentiate the instanced statistics, a * may also appear in the label. This is again replaced with the same string used to replace the wildcards in the expressions.

For an example of a wildcard statistic in practise, see the calls per frame statistic in the sample statistics file.

Files

~/.bugle/statistics

Formulae and metadata for statistics

Environment

BUGLE_STATISTICS

If set, defines the location of the statistics file, overriding the default above.

Author

bugle is written and maintained by Bruce Merry.


Name

gldb-gui — graphical OpenGL debugger

Synopsis

gldb-gui your-program [argument...]

Getting started

The command above will start gldb-gui, but will not start your program. To do that, use RunRun. Your program will automatically stop if it generates an OpenGL error. You can also stop it manually by selecting RunStop (Ctrl+Break). See the section called “Setting breakpoints” for information on stopping your program when it calls particular OpenGL functions. You can continue your program with RunContinue (Ctrl+F9), continue until the next OpenGL function call with RunStep (F8), or kill it with RunKill (Ctrl+F2).

Tip

Your program can only be stopped or killed when it calls an OpenGL function. If your program updates its display only when necessary, it may not stop immediately. You can often force it an update by placing another window over your program and then removing it again.

The interface is separated into a number of tabs. You can browse them at any time, but the information will only be up-to-date when your program is stopped. When your program is running, the status bar will contain the text Running.

Examining OpenGL state

The initial tab is the State tab. It shows all OpenGL state that is textual rather than an image. The state is organised roughly more or less according to the state tables in the OpenGL specification. OpenGL has an overwhelming amount of state, so some tools are provided to make it easier to find answers:

  • To find a specific state, press Ctrl+F. This opens a text entry box where you can type in the name of the state.

  • To show only the states that changed since the last time the program was stopped, check the Show only modified checkbox. These states are also shown in bold.

  • To track only a small set of states, check the checkboxes next to those states, then check the Show only selected checkbox.

  • To save all the states to an XML file, click the Save button.

Examining buffers

The Buffers tab shows OpenGL buffers (vertex buffer objects). The Buffer combobox allows a buffer to be selected. By default, the buffer is decoded as a sequence of unsigned bytes, but a format specification can be filled in below the combobox to control the decoding. It works best when the entire buffer contains repetitions of repetitions of a single structure format.

Suppose that the buffer contains a sequence of vertices, each consisting of a 3 GLfloats for the position, 3 unsigned bytes for a colour, and a byte of padding to make the stride 16 bytes. Then fill in the format field with fffbbb_ or more compactly, 3f3b_. A description of the available letters for specifying types appears below the entry box.

Examining textures

The Textures tab shows OpenGL textures. The Texture combobox allows a texture to be selected, with the currently bound texture of each type shown in bold. For cubemap textures, the Face combobox allows one of the sides to be examined in detail; the default is to show two views of the cube itself. For 3D textures, a slice may be selected with the Z combobox.

The apparent size of the texture is controlled through the Zoom combobox. Fit makes the texture as large as possible while still fitting the window. The other settings set a ratio between texels and screen pixels. The toolbar also has buttons to zoom in, zoom out, set a 1:1 ratio, or fit to the window size.

The appearance of the texture may be controlled with the Mag filter and Min filter comboboxes. These settings correspond to the GL_TEXTURE_MAG_FILTER and GL_TEXTURE_MIN_FILTER in OpenGL. However, these settings are only used for displaying the texture, and do not affect your program. The Level combobox makes it possible to examine specific texture levels. The default (Auto) uses mipmapping as defined by Min filter.

In some cases, there may not be enough contrast in the texture to see any details (this is particularly true of textures that encode non-graphical information, such as lookup tables). Checking Remap range will scale the colour range up (or down) to cover the whole [0, 1] range. To perform more detailed image analysis, use the Copy button to copy the texture to the clipboard, and paste it into an external application such as the GIMP.

Note

The copy feature is only available when compiled with GTK+ 2.6 or later.

Examining framebuffers

Framebuffers may be viewed in much the same way as textures (see the section called “Examining textures”). The Framebuffer may be set to either the current window-system framebuffer, or to a framebuffer created with glCreateFramebufferEXT. Pbuffers that are no the current drawable are not supported.

Within a framebuffer, Buffer may be set to the front buffer, back buffer, depth buffer, stencil buffer or an auxiliary buffer, depending on which buffers actually exist.

Examining shaders

The Shaders tab shows the source of low-level ARB shaders and high-level GLSL shaders. Vendor-specific shader extensions are not supported. The current shader of each type is shown in bold in the combobox.

Further information about the shader may be found on the State tab.

Setting breakpoints

The Breakpoints allows breakpoints to be set on specific OpenGL functions. Immediately before calling the function, your program will be stopped and the status bar will indicate which function caused the breakpoint.

Click Add to set a new breakpoint, and enter the name of the function into the dialog box that appears. To remove a function from the list, click Remove. If you are likely to want to break on that function later, it is easier to deselect the Enabled checkbox for the function, and select it again later.

Tip

Keep in mind that a function may have multiple aliases (for example, glBeginQuery and glBeginQueryARB), and you need to select the right one.

By default, gldb-gui will stop when a function generates an OpenGL error. This can be disabled by deselecting Break on errors. Note that function breakpoints occur before the function is called, but errors occur afterwards, so gldb-gui may stop twice for the same function.

Interacting with gdb

When your program is stopped, the Backtrace tab shows the current call stack of your program, as gdb would. The first few frames (usually those up to run_filters) will be internal to bugle.

To further examine the state of your program, select RunAttach GDB. Provided that you have xterm and gdb installed, this will open a terminal window running gdb, already attached to your program. Once you have finished, you may either quit gdb and detach it from your program, or keep it open and continue in gdb.

Note

Your program needs to be running from the point of view of gdb for gldb-gui to function correctly.

Remote debugging

Debugging on a single machine is not always practical, because the target application may run full-screen, or take over the keyboard or mouse.

Several options exist to use gldb-gui on a separate machine to the target application. However, all of them require trust between the two machines involved as the debugging protocol is not error-checked and so it would be easy for either a rogue target to attack gldb-gui or vice versa.

Regardless of the method used, the GL implementation running the debugger must in some respects be at least as capable as the display running the target application. Specifically, any texture that you view is loaded into an equivalent texture in the debugger, and so the texture target and dimensions must be supported there. Note that even if bugle was built for OpenGL ES, the debugger will use OpenGL.

Remote X11, target on local display

The easiest and most robust option is to rely on the networking in the X Windowing System. From the machine containing the target, start gldb-gui with a suitable DISPLAY to place the GUI on a remote machine. Then go to OptionsTarget and set the display to the local machine (usually :0.0).

Although X11 can directly connect to a remote display over the network, this is not an encrypted connection and may not be secure. SSH has an X-forwarding option (-x), but with the default setting it does not forward GLX and so it will not work if you have compiled gldb-gui with OpenGL support. However, the -Y forwards the connection as trusted, and in this mode GLX is supported. Please see security(7) to understand the security implications of this before you proceed.

Remote X11, target on remote display

The same setup as above may be used in reverse: the target runs on a remote display, while gldb-gui runs on the local display. The disadvantage of this is that the application is now using indirect rendering, which may affect its performance as well as its behaviour.

SSH-tunnelled debugger protocol

This scenario is experimental and fragile. The debugger and target execute on separate machines, and communicate over SSH rather than through a local pipe. Because the debugger protocol was not designed for networking, this currently places severe restrictions on the machines used:

  • They must use the same byte representations for types. In particular, they must have the same endianness, and it may be necessary for them to have the same word size.

  • Any types used on the target must also be known to the debugger. Ideally, one should use the same version of bugle, compiled with the same compiler and the same OpenGL headers. In some cases it may be sufficient to copy src/data/gl.tu from one build to another and re-build (but do not run make clean, as this will cause the copied file to be regenerated).

  • The Backtrace tab and the Attach GDB action will not work.

To use this mode, go to OptionsTarget and change the mode to Remote via SSH. In the remote host, put the hostname as it will be passed to ssh(1) (it can also contain a username). You must also configure ssh to log into the machine without prompting for a password.

TCP/IP connection

This is similar to the SSH option, but does not require SSH to be available, making it suitable for embedded systems with OpenGL ES. First, start the application on the target, with the following environment variables:

  • LD_PRELOAD=libbugle.so

  • BUGLE_DEBUGGER=tcp

  • BUGLE_DEBUGGER_PORT=port

  • BUGLE_DEBUGGER_HOST=host (optional)

This will open a listener on port. By default, it will listen on all interfaces, but can be made to bind to a specific interface by setting BUGLE_DEBUGGER_HOST.

Once the target has been started, go to OptionsTarget and change the mode to Remote via TCP/IP. You will then be able to fill in the host and port of the target. Once this setup is done, select RunRun to start the debugging session.

Warning

This mode does not use any kind of authentication or encryption, so should only be used on a trusted network.

Author

bugle is written and maintained by Bruce Merry.

See also

bugle(3), ssh(1), security(7)


Name

gldb — console-based OpenGL debugger

Synopsis

gldb your-program [argument...]

Description

Note

gldb(1) has been almost entirely superseded by gldb-gui(1), and is not actively maintained. You should try gldb-gui(1) first and only use gldb(1) if gldb-gui(1) does not work.

gldb is a front-end debugger to bugle(3), modelled on gdb(1). It can set breakpoints on OpenGL functions, and by default will stop whenever the program causes a GL error. Pressing Ctrl+C will also cause the running program to stop.

Commands

chain name

Specifies the name of the filter-set chain to use from the configuration file ~/.bugle/filters. If name is none then the default (no filters) is used.

help

Shows the list of commands, with brief descriptions.

run

Starts the program.

continue

Continues running the program.

step

Runs the program until the next OpenGL call.

kill

Kills the running program.

break function

Sets a breakpoint on the OpenGL function function.

break error

Breaks on OpenGL errors. This is the default behaviour.

unbreak function

Clears a breakpoint on function.

unbreak error

Prevents breaking on OpenGL errors.

quit

Exits gldb.

backtrace

Prints a stack trace using gdb(1)

gdb

Starts gdb(1) and attaches it to the program.

Note

The program will be waiting for commands from gldb, so continuing the program will have no effect.

state state

Queries the OpenGL state state. If state is omitted, all state for the current context is shown. Try first running the command without argument to see how the states are arranged, as some state is nested. For example, the width of the default 2D texture is referenced as GL_TEXTURE_2D.0.0.GL_TEXTURE_WIDTH. Tab completion is also supported.

screenshot filename.ppm

Captures a screenshot from the back buffer, and saves it to filename.ppm in ppm(5) format. Since the back buffer is used, you are not guaranteed a complete picture. For a complete picture, put a breakpoint on glXSwapBuffers and call this command from there.

enable filter-set, disable filter-set

Enables or disables a filter-set on the fly. This is still experimental, and won't work for most filter-sets (because they expect to perform initialisation when the context is created). Dependent filter-sets will automatically be enabled, but will not be automatically disabled.

Environment

BUGLE_CHAIN, BUGLE_DEBUGGER, BUGLE_DEBUGGER_FD_IN, BUGLE_DEBUGGER_FD_OUT

Internal environment variables used to communicate between the debugger and the library.

LD_PRELOAD

Used internally to force loading of the library.

Bugs

On some systems, the gdb command will cause some of the processes involved to be stopped. The cause is currently unknown. The work-around is to use another terminal to manually connect gdb(1) to the process.

Author

bugle is written and maintained by Bruce Merry.


Name

bugle-camera — allow the camera to be manipulated

Synopsis

filterset camera [key inactive]
{
    speed "1.0"
    mouse_dga "no"
}

Description

This filter-set allows you to take over the camera in an OpenGL application and move it about. This is particularly useful for testing visibility culling and level-of-detail (LOD), as these will not change as the camera is moved.

To use it, make sure it is activated, then move to the mouse to control the camera angle and the Up, Down, Left and Right keys to move the viewpoint. The camera model is a free camera, so it will not maintain a defined up direction. There are a few other useful keys, described in the section called “Options”.

This filter-set supports activation and deactivation; the recommended use is to have it initially inactive and use a key to take over control when desired (see bugle(3)).

Since this filter-set is based on modifying OpenGL state without telling the application, there are significant limitations:

  • The projection matrix, and in particular, the near and far clip planes, are not altered. Thus, trying to move in too close or out too far could cause objects to be clipped away.

  • Various fancy rendering techniques involve rendering a quad that is carefully aligned to the screen; altering the camera will break such techniques. There is ultimately no general fix as it is impossible to know when an application is dealing with the real world. If you are writing such an application and wish it to work with this filter-set, you should use a vertex program that ignores the model-view matrix in situations where you do not want this filter-set to interfere.

  • Applications that rely on the feedback buffer are likely to break.

Options

mouse_dga

This is a boolean option which should be enabled when debugging an application that uses XDGA(3) to get relative motion data from the mouse. If the camera goes all over the place as soon as you move the mouse, try enabling this option (SDL-based applications are the main culprits).

speed

This sets the speed at which the camera moves. Since each application has a different scale, you will need to adjust the value for each application (but dynamic control is also possible; see below).

key_forward, key_back, key_left, key_right

These are the keys for moving the camera. They default to the arrow keys.

key_faster, key_slower

These keys control the speed of the camera, doubling or halving it respectively. They default to PageUp and PageDown.

key_reset

This key cancels any alterations made, restoring the camera to where the application thinks it is. There is no default.

key_toggle

This key alternately releases and recaptures the mouse. It can be useful if you need to use the mouse in another window without completely disabling the filter-set (which would also restore the camera position). There is no default.

This toggles display of the original view frustum. If this driver supports GL_NV_depth_clamp, depth clamping is used to prevent the frustum from being clipped to the near and far clip planes. There is no default.

Author

bugle is written and maintained by Bruce Merry.

See also

bugle(3)


Name

bugle-checks — check for errors that OpenGL defines as undefined behaviour

Synopsis

filterset checks

Description

While OpenGL checks for many error conditions, there are some for which the specification does not define behaviour. These instances are usually in performance-critical paths where error-checking would impact on performance. This filter-set checks for some of these conditions. Because of the high cost of the checks, it is only intended for debugging.

The checks that are made are for:

  • Sourcing vertex or index data from unreadable client memory.

  • Sourcing vertex or index data from outside the valid range of a vertex buffer object.

  • Calling glVertex from outside glBegin/glEnd.

  • Setting client state from inside glBegin/glEnd.

  • Specifying indices to glDrawRangeElements that are outside the specified range.

When an error is detected, a warning is written to standard error and the call is ignored. There is currently no convenient way to trap the errors in a debugger (you can, however, find the message in the bugle source and set a breakpoint on the appropriate line).

Bugs

Due to the design of C, there is no way to perfectly reliably check for vertex array overruns, although memory debuggers can help.

Mesa, up to 6.5.1, has a bug that prevents generic vertex attributes from being validated.

Author

bugle is written and maintained by Bruce Merry.


Name

bugle-eps — captures vector graphics representatios of scenes

Synopsis

filterset eps
{
    filename "screenshot.eps"
    key_eps "key"
    title "My screenshot"
    bsp "no"
    buffer "10000000"
}

Description

This screenshot is similar to bugle-screenshot(7), but instead of a raster image, it produces a vector graphic suitable for printing. This is achieved through gl2ps, which is incorporated into bugle. The supported formats are Postscript, Encapsulated Postscript (EPS), Portable Document Format (PDF) and Scalable Vector Graphic SVG).

The capturing process utilises the OpenGL feedback buffer (see glFeedbackBuffer(3)), which creates some inherent limitations. No per-fragment effects (such as texturing or bitmap rendering) are captured, not will vertex programs work correctly. Essentially, the colour of each vertex must be either directly specified or determined by the OpenGL lighting model.

Options

filename

The file to which the screenshot will be written. The extension is used to determine the file format. Valid extensions are .ps, .eps, .pdf and .svg.

key_eps

The key-press which triggers the snapshot.

title

The title that is embedded in Postscript and EPS files.

bsp

If this boolean is enabled, the depth sorting is done with a BSP tree to give accurate results. This may be necessary to get correct results in scenes with complex occlusion, but it is much slower.

buffer

The number of entries to allocate for the feedback buffer. If this is too low, the feedback buffer will overflow and the screenshot will fail. The default should be enough for most simple scenes, but for highly complex scenes it may be necessary to create a larger buffer.

Author

bugle is written and maintained by Bruce Merry.

See also

bugle(3), glFeedbackBuffer(3)


Name

bugle-error — detect errors in OpenGL calls

Synopsis

filterset error

Description

This filter-set does not take any visible action on its own, but provides a service to other filter-sets. It calls glGetError(3) after every OpenGL call to detect OpenGL errors (it does not detect X errors).

Usually you will not need to explicitly load this filter-set; if you want to be informed of OpenGL errors, either use the showerror filterset, or gldb-gui(1). However, you may occasionally see the message

An OpenGL error was detected but will be lost to the application.

This means that bugle's internal error-checking code accidentally collected an error caused by one of your calls, and thus if your application later called glGetError(3) it would not be informed of the error. However, if you add the error filter-set, it will catch the error first and your application will be correctly informed of the error.

Bugs

Because the error reporting semantics of OpenGL are not completely defined (in particular, an implementation may choose how many error flags it has), it is impossible to guarantee that this filter-set is completely transparent to the application. However, the first call to glGetError(3) always return an error, and in practice this is all that is necessary.

Author

bugle is written and maintained by Bruce Merry.

See also

bugle(3), bugle-showerror(7), bugle-trace(7), glGetError(3)


Name

bugle-exe — record a compilable log of OpenGL calls made

Synopsis

filterset exe
{
filename "exetrace.c"
}

Description

This filter-set provides a log of the OpenGL calls made. Unlike the bugle-trace(7) filter-set, the log is output as C code that can be compiled to reproduce the function calls.

Warning

This filter-set is still experimental and incomplete. For details, see below.

Currently, only OpenGL function calls are recorded, not calls to WGL/GLX/EGL or the native windowing system. Handles returned by functions such as glGenTextures and glCreateShader are not remapped, so re-running a compiled trace will only work if handles are generated deterministically by the OpenGL implementation. Client-side vertex arrays are also not yet supported.

The generated code merely consists of a function per frame, and a lookup table of those function. It is up to you to provide a harness in which to run this code.

Options

filename

The name of the C file to generate. Defaults to exetrace.c.

Bugs

See the limitations above. This filter-set is also vulnerable to any errors or omissions in the tables that tell bugle how many values are stored in an array passed to OpenGL.

Because the filter-set examines arguments and follows pointers, it is possible to crash it by passing invalid values, particularly invalid pointers.

Author

bugle is written and maintained by Bruce Merry.


Name

bugle-extoverride — hide OpenGL extensions from an application

Synopsis

filterset extoverride
{
    version "1.5"
    disable "all"
    disable "extension"
    enable "extension"
}

Description

The extoverride filter-set modifies the version and extension strings to hide driver capabilities from the application. The primary use is to test an application to ensure that it works correctly on drivers that do not offer these capabilities.

Apart from modifying these strings, a warning is printed to the log if any function from one of these extensions is called.

Options

version

Sets a new value for GL_VERSION. However, if the true value is lexicographically smaller than this value, the true value is used.

disable "all"

By default, extensions are exposed unless explicitly disabled. This option reverses the behaviour to hide all extensions that are not explicitly enabled.

disable "extension"

Hides the named extension from the application. A warning is printed if the extension was not known at the time bugle was compiled; in this case it will still be hidden, but there will not be any warning if it is used anyway.

enable "extension"

Like the disable option, but enables an extension when the default is disabled.

Bugs

Warnings are only printed if functions from the disabled extensions are called. At present, no warning will be printed if tokens from those extensions are passed (which is difficult to determine, since multiple tokens may share the same numeric value). Furthermore, some extensions alter semantics without explicit functions or tokens, such as GL_ARB_texture_non_power_of_two; no warnings are issued if these extensions are used.

Also note that extension loader libraries may interfere with the warning mechanism. For example, GLee uses wrappers that cause illegal function calls to be silently ignored.

Author

bugle is written and maintained by Bruce Merry.


Name

bugle-frontbuffer — force rendering to the front buffer

Synopsis

filterset frontbuffer

Description

The frontbuffer filter-set overrides the draw buffer, setting it to GL_FRONT. This is most useful when used within gldb-gui(1) in order to see how a scene is built up batch by batch.

Bugs

As with any filter-set that modifies OpenGL state, it may break complex rendering techniques like render-to-vertex-buffer.

Author

bugle is written and maintained by Bruce Merry.

See also

bugle(3), gldb-gui(1), glDrawBuffer(3)


Name

bugle-log — configure logging output from other filter-sets

Synopsis

filterset log
{
    filename "bugle.log"
    file_level "4"
    stderr_level "3"
    flush "no"
    format "[%l] %f.%e: %m"
}

Description

The log filter-set does not do any logging itself; instead, it provides logging services to other filter-sets. It is always loaded, but it may be explicitly listed in the configuration file to set options. The log is always written to standard error, but it can be written to file as well. It is also possible to control the log level.

Options

filename

This sets the file for logging. Logging is still done to standard error. Note that with the default settings, the file log is more verbose than the standard error log.

file_level

The log level for the log file, where a higher number means more verbose logging. The levels are:

0

No logging at all

1

Errors, usually leading to immediate termination

2

Warnings, usually affecting bugle's functionality

3

Notices, usually OpenGL errors or undefined behaviour

4

Info from filtersets that generate logs, such as bugle-trace(7)

5

Debugging messages

stderr_level

Similar to file_level, but for logging to standard error. The default is 4 for a file and 3 for standard error.

format

Overrides the default log format. The following printf-style escapes are recognised:

%l

log level

%f

filter-set

%e

event

%m

the log message itself

%p

process ID

%t

thread ID

%%

a literal %

Author

bugle is written and maintained by Bruce Merry.


Name

bugle-logstats — log statistics to file

Synopsis

filterset logstats
{
    show "statistic1"
    show "statistic2"
}

Description

The logstats filter-set writes statistics to the bugle log (see bugle-log(7)). The statistics are gathered from other filter-sets.

Use the show option for each statistic that should be logged to file. The option values must match names defined in ~/.bugle/statistics.

Bugs

No statistics are reported for the first frame.

Files

~/.bugle/statistics

Formulae and metadata for statistics

Environment

BUGLE_STATISTICS

If set, defines the location of the statistics file, overriding the default above.

Author

bugle is written and maintained by Bruce Merry.


Name

bugle-screenshot — takes screenshots and captures video

Synopsis

filterset screenshot
{
    filename "screenshot.ppm"
    key_screenshot "C-A-S-S"
}
filterset screenshot C-V inactive
{
    video "yes"
    filename "video.avi"
    codec "mpeg4"
    bitrate "1000000"
    allframes "no"
}

Description

The screenshot filter-set can be used in one of two modes, corresponding to the two examples above. In the first, a particular key-press causes a screenshot to be taken, which is written to file in ppm(5) format. In the second, a video stream is captured and encoded to one of a range of formats with ffmpeg(1).

Options

video

This option controls the mode: either screenshots on request or a video stream. This filter-set supports activation and deactivation, so it is possible to record video only on demand.

filename

The file to which the image/video is written. In the case of an image, if the filename contains a % it is used as a format string for sprintf(3) with the frame number passed as the parameter.

key_screenshot

The key combination used to capture a screenshot.

codec

The codec to use when capturing a video. Refer to the documentation for ffmpeg(1) for a list of valid codecs. Some codecs require special setup and may not work, but common codecs such as mpeg4 and huffyuv should work.

bitrate

The approximate number of bits per second to use for video encoding.

allframes

By default, a frame is captured 30 times per second. If this option is set, every frame is captured. Note that the video file will still play at 30fps, so the speed will vary unless the application has been written to use a fixed time-step between frames for its internal animation (this is a useful way to produce smooth video if the capturing overhead is otherwise too high).

lag

Sets the latency between frame capture and encoding. If GL_EXT_pixel_buffer_object is available, setting this option to a value greater than 1 can help mask readback latency, at the expense of video memory.

Author

bugle is written and maintained by Bruce Merry.

See also

bugle(3), ppm(5), ffmpeg(1)


Name

bugle-showerror — reports errors in OpenGL calls

Synopsis

filterset showerror

Description

This filter-set is a light-weight method of detecting OpenGL errors in applications, where gldb-gui(1) is not useable for some reason (for example, when debugging a full-screen application). It writes OpenGL errors to the log (see bugle-log(7) for details of the log). With the default log settings, the error will be reported to standard error.

Author

bugle is written and maintained by Bruce Merry.

See also

bugle(3), bugle-error(7), bugle-log(7), gldb-gui(1), glGetError(3)


Name

bugle-showextensions — show which extensions are used by an OpenGL application

Synopsis

filterset showextensions

Description

The showextensions filter-set can be used to determine what version of OpenGL and which extensions are used by a particular application. It can be used to check that an application does not accidentally depend on an OpenGL version that is not targetted. The most common error is calling a core OpenGL function (for a recent version of OpenGL) when one intended to use an older and more widely supported extension.

Note that it can only report what is used, not what is required, which may be different if the application uses certain features only after detecting them (but see bugle-extoverride(7) for a way to handle this). It also only tests the run-time usage; the compile-time usage may be different.

Two methods are used for detection: the functions called and the enumerants passed to functions. The former is quite reliable, since different entry points are used for the core and extension versions of the same function. The latter is necessary to detect extensions such as GL_SGIS_generate_mipmap which do not introduce new function calls, but it is less reliable as many enumerants share values. Some extensions are not detected at all: GL_ARB_texture_non_power_of_two does not introduce any tokens or functions, and some promoted extensions (such as GL_ARB_pixel_buffer_object) have additional semantics to their predecessors but again introduce no new tokens or functions.

Output

A typical output is the following:

Min GL version: GL_VERSION_1_5
Min GLX version: GLX_VERSION_1_2
Used extensions: GL_ARB_shader_objects GL_ARB_vertex_shader

This indicates that the application used OpenGL 1.5 and GLX 1.2 (and possibly some extensions that are incorporated into OpenGL 1.5), as well as the extensions listed.

Bugs

  • Detection is not completely reliable, as described above.

  • Sometimes extensions are listed even though they are already part of the core version listed.

  • It is assumed that OpenGL 1.1 and GLX 1.2 are used; there is no way to detect whether an application would work on OpenGL 1.0 or GLX 1.1.

Author

bugle is written and maintained by Bruce Merry.


Name

bugle-showstats — render statistics over the display

Synopsis

filterset showstats
{
    show "statistic1"
    show "statistic2"
    graph "statistic3"
}

Description

The showstats filter-set display statistics gathered by other filter-sets over the rendered display. Statistics can be displayed either as text or as graphs.

Options

show

Specifies a statistic to display as text. The name must match an entry in ~/.bugle/statistics.

graph

This is like the show option above, but displays a graph rather than text.

time

The interval (in seconds) between updating the statistics. The default is one second.

key_accumulate

By default, statistics are averaged over the time interval specified above, making them approximately instantaneous rates. Pressing this key will cause the display to instead show the average from the time the key was pressed until the current moment.

key_unaccumulate

This key cancels the effect of key_accumulate.

Files

~/.bugle/statistics

Formulae and metadata for statistics

Environment

BUGLE_STATISTICS

If set, defines the location of the statistics file, overriding the default above.

Author

bugle is written and maintained by Bruce Merry.


Name

bugle-stats_basic — gather frame rate statistics

Synopsis

filterset stats_basic

Description

The stats_basic filter-set provides signals for the number and frames and the elapsed time to other filter-sets. It is sufficient for capturing frame rate or frame time, and is needed for most other statistics filter-sets.

Author

bugle is written and maintained by Bruce Merry.


Name

bugle-stats_calls — gather call frequency count

Synopsis

filterset stats_calls

Description

This filter-set generates a count of the number of times each OpenGL function is called. The signal associated with glSomeFunction is called calls:glSomeFunction.

The expected use is with the calls per frame statistic defined in the sample statistics file, which shows the counts for all functions called at least once during the frame.

Author

bugle is written and maintained by Bruce Merry.


Name

bugle-stats_calltime — gather call timing

Synopsis

filterset stats_calltimes

Description

This filter-set measures how long is spent in each OpenGL call. The signal associated with glSomeFunction is called calltimes:glSomeFunction.

In addition, there is a signal called calltimes:total, which measures the total time spent in all GL calls.

The expected use is with the average time per call statistic defined in the sample statistics file, which shows the average time spent in each call.

Note that these times include some overhead from bugle itself, so it will be most useful for calls that involve significant work (such as shader compilation/linking) or which may stall the CPU (such as glReadPixels).

Author

bugle is written and maintained by Bruce Merry.


Name

bugle-stats_fragments — gather fragment counts

Synopsis

filterset stats_fragments

Description

The stats_fragments filter-set provides signals for the number of fragments to other filter-sets. It must be listed in a chain that uses any statistics related to fragment counts.

It is simply a wrapper around GL_ARB_occlusion_query, so a fragment is defined exactly as in that extension (and OpenGL 1.5), and will not work unless that extension is supported.

Bugs

Fragment counting will not work in applications that use occlusion queries. A warning is displayed when this is detected.

Author

bugle is written and maintained by Bruce Merry.


Name

bugle-stats_nv — gather performance data from NVPerfSDK

Synopsis

filterset stats_nv
{
    flush "yes"
}

Description

The stats_nv filter-set extracts data from certain NVIDIA GPUs using NVPerfSDK. This filter-set is only built if the appropriate header file is present at compile time, and also requires a suitably configured driver and GPU (refer to the NVPerfSDK documentation).

The possible statistics can be seen in the example statistics file (doc/examples/statistics in the bugle source distribution). It is important to read the NVPerfSDK documentation to understand what the different types of statistics are, what they mean, and the limitations of the hardware interface.

Options

flush

If set, a glFinish(3) will be issued immediately prior to sampling the counters. This guarantees that events will be accounted to the correct frame, but will cause pipeline stalls.

Bugs

Because NVPerfSDK operates across OpenGL contexts, it will count events from outside the debugged application. In particular, using bugle-showstats(7) to view the results will alter the statistics.

Author

bugle is written and maintained by Bruce Merry.

See also

bugle(3), bugle-statistics(5), NVPerfSDK documentation


Name

bugle-stats_primitives — gather triangle and batch counts

Synopsis

filterset stats_primitives

Description

The stats_primitives filter-set provides signals for the number of triangles and batches to other filter-sets. It must be listed in a chain that uses any statistics related to triangle or batch counts.

Bugs

  • Display lists that call other display lists are not handled correctly, and if these secondary lists make any draw calls they will not be included in statistics.

  • Use of the GL_NV_primitive_restart extension will yield incorrect results.

Author

bugle is written and maintained by Bruce Merry.


Name

bugle-trace — record a log of OpenGL calls made

Synopsis

filterset trace
filterset log
{
    filename "trace.txt"
}

Description

This filter-set provides a log of the OpenGL calls made. For each call, the function name, the parameters and the return value (if any) are recorded. Where appropriate, symbolic names are shown for GLenum parameters, and pointers are followed to show the correct number of elements.

Options

There are no options to control this filter-set. All logging is done through bugle's logging system (see bugle-log(7)), and options such as filename and log format can be modified there.

Output

Here is a sample log output

[INFO] trace.call: glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
[INFO] trace.call: glLoadMatrixd(0xbfffe610 -> { { 0, -0.29661, 1.22295, 0 }, { 1.22295, 0, 0, 0 }, { 0, 1.18644, 0.305739, 0 }, { 0.037888, 1.61781, -1.52576, 1 } })
[INFO] trace.call: glActiveTextureARB(GL_TEXTURE0)
[INFO] trace.call: glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, 0xbfffe5d0 -> { 0.778524, 0.778524, 0.569631, 0 })

Bugs

Some enumerants share values, so you may see a different symbolic name in the log than in your source code. It is believed that this should be limited to cases where extensions share a value for semanticly equivalent symbols; if you find a case where this is not true, please inform the author.

Because the filter-set examines arguments and follows pointers, it is possible to crash it by passing invalid values, particularly invalid pointers.

Backwards compatibility

In previous versions, the trace filter-set also reported OpenGL errors to the log. This is now handled by the showerror filter-set (see bugle-showerror(7)).

Author

bugle is written and maintained by Bruce Merry.


Name

bugle-unwindstack — recover a stack trace after a segmentation fault

Synopsis

filterset unwindstack

Description

Some OpenGL drivers (particularly proprietry drivers) are compiled without frame pointer information. The result is that if you pass a bad pointer to the driver, causing it to segfault, gdb(1) is unable to produce a stack trace showing that location of the fault. This filter-set uses some ugly hacks to try to correct this.

When using this filter-set and debugging your application in gdb(1), the segmentation fault will still leave you without a stack trace. However, if you continue running, you will get a second segmentation fault, at which point a stack trace is available.

Note that the call that causes the segmentation fault may not be the direct cause; for example, a bad pointer passed to glVertexPointer might only cause a segmentation fault in glDrawArrays. See also the bugle-checks(7) filter-set, which does some aggressive error-checking and can detect some of these conditions.

Bugs

The method used to recover the stack trace violates POSIX rules (and common sense) about the use of setjmp. It works for me under Linux with NVIDIA drivers, but your mileage might vary.

Author

bugle is written and maintained by Bruce Merry.

See also


Name

bugle-wireframe — force rendering in wireframe mode

Synopsis

filterset wireframe

Description

The wireframe filter-set overrides the polygon mode, setting it to GL_LINES. This is useful for visualising the triangulation of models.

Bugs

  • Run-time activation and deactivation are not fully supported.

  • Display lists that alter the polygon mode will cause problems.

  • As with any filter-set that modifies OpenGL state, it will break complex rendering techniques like render-to-vertex-buffer.

  • Texturing is generally disabled to make the lines more visible, but fragment programs will nevertheless continue to apply textures.

Author

bugle is written and maintained by Bruce Merry.

See also

bugle(3), glPolygonMode(3)

Appendix D. Release notes

0.0.20091026
------------
This release just fixes a compilation problem with newer versions of glext.h.
If you have successfully installed the previous version, there is no need to
upgrade.

0.0.20090801
------------
This release just fixes a compilation problem with GCC 4.4. If you have
successfully installed the previous version, there is no need to upgrade.

0.0.20090706
------------
This release just fixes compilation problems with the newest glext.h. If you
have successfully installed the previous version, there is no need to upgrade.

0.0.20090411
------------
This release fixes several bugs, and has improved tracing of EGL and GLX.

0.0.20090311
------------
This release is packed with new debugger features:
- Buffer viewer
- Info log view
- Stop on shader compile/link failure
It also generally improves portability and cross-compilation support, adds
a target for OpenGL ES 1.1 on Windows, and has a lot of bugfixes as well.

0.0.20090221
------------
This release features a whole host of new features and bugfixes. Most notable
are experimental support for TCP/IP-based remote debugging and OpenGL ES 1.1.

0.0.20080824
------------
The texture view was broken in the previous release - this release fixes it.
There are no other changes.

0.0.20080803
------------
This release fixes a number of small bugs. Refer to the ChangeLog for details.

0.0.20080728
------------
This release fixes some problems with OpenGL ES support, and with building
the debugger on Windows. Desktop UNIX users do not need to upgrade.

0.0.20080716
------------
This is a major new release that adds experimental support for Windows and for
OpenGL ES 2.0. These ports are still in the early stages of development, and
many features don't yet work. Nevertheless, you're encouraged to try them out.

Note that you must delete the old contents of $PREFIX/lib/bugle/*.so when
upgrading, as otherwise stale modules will be loaded into bugle.

0.0.20080303
------------
Apart from a few bug-fixes, this release adds checks for incomplete textures to
the 'checks' filter-set. It now also requires GLEW for the image viewers in
gldb-gui - if you find those tabs have vanished then you should install
it from glew.sf.net and reconfigure bugle.

0.0.20080215
------------
This release just fixes a few minor bugs.

0.0.20080123
------------
This is mostly a bugfix release, fixing compilation under old versions of
GTK+ and with some NVIDIA header files. There is also some new reflection
functionality for plugin authors.

0.0.20080103
------------
There are a number of minor bug-fixes (see the ChangeLog), but the major
change in this release is that the filter-set API has been stabilised and made
available to users through installed header files. If you are interested in
writing your own filter-sets, refer to doc/html/extending.html.

0.0.20071206
------------
This release has a lot of changes, but it's mostly under the hood to
start bringing bugle to a point where 3rd parties can easily write and
ship filter-sets. The most obvious change for users is that remote
(network) debugging is now easier to do. See gldb-gui(1) for details
(seriously, read it, as it's still very experimental and the best way
isn't what the GUI might suggest).

NB: if you are upgrading, you MUST delete
/usr/local/lib/bugle/stats.so, otherwise you will get an error about
cyclic dependencies on startup.

0.0.20071108
------------
This release just fixes the generation and installation of the
documentation.

0.0.20071107
------------
This release fixes a number of compilation failures, crashes, and
performance bugs. The manual pages have all been converted to DocBook,
giving much higher quality HTML versions. Some improvements were made
to the documentation at the same time.

Some internals were redesigned, and so some new bugs may have been
introduced. If you find any new bugs, please email me
(bmerry@users.sourceforge.net).

0.0.20071009
------------
Interception of functions that are not filtered is now significantly
faster (showfps will have far less overhead, for example, since it only
acts on glXSwapBuffers).

This release also changes the way startup is handled to better
facilitate libraries like QT and SDL that dynamically load libGL.so.
You no longer need to set an environment variable for SDL applications.
Please let me know of any regressions, particularly on non-GNU
systems.

0.0.20070718
------------
It is now possible to view high-level geometry shaders in the shader
viewer. There is also a minor bug-fix for the framebuffer viewer when
using FBOs.

0.0.20070528
------------
The logging system has been heavily reworked. If you are upgrading,
please read the manpage for bugle-log(7) and bugle-trace(7) and update
your ~/.bugle/filters as appropriate.

There is also a new filter-set for hiding extensions (extoverride) and
miscellaneous bugfixes.

0.0.20070325
------------
I've added support for several of the new extensions exposed by the G80
(aka GeForce 8800); see the ChangeLog for details. These are not fully
tested, especially where NVIDIA haven't released support in the
drivers, so let me know if anything breaks.

The state viewer will also look a little different: some missing
extension suffices have been added (e.g., GL_TEXTURE_RECTANGLE_ARB was
missing the _ARB) and the ordering has been changed to better mirror
the order in the OpenGL 2.1 state tables.

0.0.20070217
------------
This release fixed a number of bugs and makes some internal redesigns.
The most visible new feature is that strings in the gldb-gui state
viewer are now displayed unescaped, making it easier to read multi-line
strings such as shader info logs.

0.0.20070107
------------
There are several bug-fixes related to using gldb-gui with pbuffers and
framebuffer objects. In addition, it is possible to save the current
state to an XML file, and the camera filter-set has the option to
drawing the original view frustum.

0.0.20061227
------------
There is now an option in the texture and framebuffer viewers to remap the
range. This is useful for viewing textures with data outside the [0, 1]
range as well as images with low dynamic range. There are also many bugfixes;
in particular, BuGLe should now work much better on ATI cards.

0.0.20061110
------------
This is a quick-fix release for ccache. If you have successfully
installed 0.0.20061109 there is no need to upgrade.

0.0.20061109
------------
A number of bugs are fixed in this release. The most important is that
screenshots and video capture are working again, having been broken in
the previous release.

0.0.20061022
------------
The statistics system has been completely rewritten and is now a lot
more powerful, supporting customisable statistics, graphs, batch
counts, NVPerfSDK and lower overhead.

You will need to update your ~/.bugle/filters file to use any
statistics (see the examples in doc/examples/filters), and you will
also need to copy doc/examples/statistics to ~/.bugle/statistics.

0.0.20060913
------------
While there is no one feature that makes this release special, it has a
huge number of minor bug-fixes and improvements, mostly to the GUI
debugger. See the ChangeLog for details.

The GUI debugger has almost achieved feature-parity with the text debugger
(run-time enabling and disabling of filter-sets being one missing feature).
I haven't really been maintaining the text debugger, and I'm thinking of
discontinuing it. If there are reasons why you still prefer the text
debugger, let me know soon so that I can reconsider.

0.0.20060828
------------
This release fixes a serious bug in the framebuffer viewer that would
cause it to crash on applications doing render-to-texture. If your
application does not use render-to-texture via
GL_EXT_framebuffer_object you do not need to upgrade.

0.0.20060827
------------
gldb-gui now has a framebuffer viewer! You can view the front and back
buffers, plus depth, stencil and auxiliary buffers as well as
framebuffer objects. There is also better support for 3D textures in
the texture viewer, and assorted bug-fixes.

0.0.20060813
------------
This release makes some improvements to the texture viewer - in
particular, shadow textures will be displayed in grey-scale rather than
crashing, and luminance textures will appear in grey-scale rather than
red-scale. Refer to the ChangeLog for miscellaneous other bug-fixes and
improvements.

0.0.20060528
------------
This release fixes several important bugs (see the ChangeLog for
details). It also introduces some flexibility into the logging format
and allows gldb and gldb-gui to step to the next GL call. The
filter-sets are now documented in individual manual pages.

0.0.20060429
------------
This release fixes a nasty bug (introduced in 0.0.20060416) that causes
the trace filterset to crash on certain calls, and may cause other
spurious behaviour. All users of 0.0.20060416 should upgrade.

0.0.20060416
------------
This release adds a camera filterset, which allows the user to take
over the camera. It won't work with advanced rendering techniques (such
as any kind of post-processing), but is a handy way to test LOD and
visibility culling.

0.0.20060306
------------
This is a minor update that fixes some build problems on Debian
testing. Users who successfully built and installed 0.0.20060224 do not
need to upgrade.

0.0.20060224
------------
This release adds code to intercept keypresses from the application.
Screenshots are now taken by keypress rather than on every frame, and
it is possible to manually start and stop filter-sets such as video
recording (particularly useful if the framebuffer is resized before
starting, as a resize normally terminates encoding) and wireframe. See
the manual page for details.

gl2ps, a library to create Postscript and similar files from the
feedback buffer, has been incorporated, allowing one to create vector
graphic screenshots. This is handled by the 'eps' filterset, although it
actually supports PS, PDF and even SVG). Of course, this has the usual
limitations of the feedback buffer (no per-pixel effects), so don't
expect to capture Doom 3, but it works beautifully for glxgears.

There are also some bugfixes, and in particular GTK+ 2.8 and pre-release
versions of ffmpeg should now be better supported.

WARNING: the options to the screenshot filter-set have changed, and the
epswire filter-set has been replaced by the eps filter-set. You will
need to update your ~/.bugle/filters file. Refer to the example in
doc/examples/filters for a sample. I've removed the option to set a
start frame for video capture (since you can now press a key to start).
If you need the old behaviour let me know and I can restore it.

0.0.20060101
------------
This release greatly improves the texture viewer in gldb-gui, as well as
fixing a number of bugs. It also fixes a dubious shortcut (read: bug)
that caused all kinds of havoc with ATI drivers. If previous releases
have caused weird problems when using an ATI card (whether with gldb,
gldb-gui or a filter), give this release a try.

I have had intermittent problems with gldb-gui crashing due to "an X
Window System error". If you can reproduce this, let me know so that I
can try to fix it.

0.0.20051112
------------
There is now a graphical debugger, gldb-gui. The GUI is still in very
early development, and anything complicated will break it (in
particular, 1D, 3D and cube-map textures are not supported in the
texture viewer).

There is also support for several new extensions in gldb's state viewer,
including GL_ARB_vertex_program, GL_ARB_fragment_program,
GL_ARB_texture_rectangle, GL_EXT_texture_filter_anisotropic, and
GL_EXT_framebuffer_object.

0.0.20050221
------------
This version is a major update. The code generator, state manager and
object tracker have all been rewritten and work a lot better, and
substantial changes have been made to the call dispatcher to reduce
overhead. Almost all of OpenGL 2.0 is now supported. It should also be
slightly more portable, due to the use of ltdl to load modules.

As a result, there are probably lots of new bugs. Please send them to
me at bmerry@users.sourceforge.net.

This version also adds the 'checks' filter-set. See the man page for
details.

0.0.20041123
------------
The major news is the news stats and showstats filter-sets, which can
display frame rate, triangle count and fragment count - as an overlay
on the rendered frame! There has also been some work to reduce overhead,
so that the fps counter will be reasonably accurate.

0.0.20041108
------------
Some bugfixes and minor improvements, including a filter-set to tell
you what extensions are being used. See the ChangeLog.

0.0.20041025
------------
Minor update, the most important fix being that extension functions
will now be properly intercepted. If the previous version worked for
you, and you are not using extensions, then you shouldn't need to
update.

0.0.20041011
------------
This is a fairly major update to the internals, although not much of it
is visible to the user. The biggest changes are the ability to pass
options to the program that gldb will run, and a 'screenshot' command
within gldb to take screenshots on request.

WARNING: see the README for upgrade instructions. Simply installing
over an older version will break things. You will also need to add the
'trace' filter-set to your existing configuration files if you want the
tracing functionality originally provided by the 'log' filter-set.

0.0.20040903
------------
This release adds a few minor improvements to the video capture facility.
See the ChangeLog.

0.0.20040719
------------
The big changes are improvements to the debugging facility, gldb. Pressing
Ctrl-C will now stop the program (ala gdb), and it is possible to query
OpenGL state. Refer to the gldb(1) manual page for details.

This release also offers much better thread safety, and it should now
be mostly possible to use bugle even with programs that render
simultaneously from multiple threads. However, the debugger will not
work on a multi-threaded program, and there are still a few known race
conditions.

Finally, there is also a preliminary video capture mode. It is still
somewhat slow and experimental.

0.0.20040614
------------
This release adds the gldb debugging tool. This replaces the rather
primitive debugging mode of earlier releases, where you specified
breakpoints in the config file. See the man page for instructions on
using gldb.

You will probably need to modify your configuration file, to take
account of the following changes (or you can just copy the one in
doc/examples/filters.
- The invoke filter-set is automatically loaded. You may still specify
  it, but omitting it makes no difference.
- The debugger filter-set should no longer be specified. It is
  automatically loaded by the debugger, and attempting to use it
  without the debugger will lead to errors.
- The "error" filter-set has been renamed to "showerror".
  An "error" filter-set still exists, but only detects errors for the
  benefit of other filter-sets. For example, the "log" filter-set will
  log errors if the "error" filter-set is used.

0.0.20040609
------------
Minor bugfixes only.

0.0.20040606
------------
This is the first public release of BuGLe. Please read the README file
first, as the software it still pretty rough.

Appendix E. Change Log

0.0.20091026
------------
* Better detection of anonymous types in budgie
* Fix bogus aliasing of glGetObjectParameter*APPLE in newer glext.h

0.0.20090801
------------
* Make compilation work with GCC 4.4

0.0.20090706
------------
* Make compilation work with latest glext.h

0.0.20090411
------------
* Fix display of uniform arrays to show all elements, not just one (closes: #53)
* Fix input system to not call X functions inside an event predicate (closes: #55)
* Improved symbolic display of enums for EGL and GLX
* Added block parameter to bugle_api_enum_name and bugle_api_enum_extensions
* Removed bugle_count_glx_attributes in favour of generic bugle_count_glwin_attributes
* Removed bugle_dump_glx_attributes in favour of generic bugle_dump_glwin_attributes
* Added .bc entries for dumping of attribute lists, particularly in EGL
* Add include dir to bugle.pc to make compilation of third-party plugins work better
* Fix crashes when using repeat counts in buffer viewer
* Fix segfault on starting command-line gldb
* Add stats_calltimes filterset
* Made specifying a command on the command-line optional

0.0.20090311
------------
* Give budgie a separate configure.ac and Makefile.am, to make cross-compilation easier
* Reverted to old version of gnulib without GPLv3 code
* Fix missing symbol globjects_delete_single in ES2.0 port
* Fix compilation errors due to ssize_t not being defined
* Fix extraction of uniforms
* Tweaks to the debug protocol and fixes to the related code
* Updated protocol documentation as part of the user manual
* Support stopping on shader compilation or link failure
* Display of info log
* Fix Windows build of the debugger filter-set
* Fix compilation error in stats_nv filter-set
* Fix display of 3D textures in the debugger
* Buffer object viewer
* Support for OpenGL ES-CM 1.1 on Windows
* Fix a build problem when using Cygwin Perl in a MinGW shell
* Fix installation instructions to require building GLEW from source
* Fix an array overrun during startup in the camera filter-set

0.0.20090221
------------
* Fix tracing support for GL_ARB_transpose_matrix
* Fix several bugs in exe filterset that made it almost unusable
* OpenGL ES-CM 1.1 support (incomplete)
* Improved dumping of glCompressedTex*Image* and glBuffer*Data
* Dump NULL pointers as "NULL" instead of whatever the printf implementation picks
* Rename 'xevent' system to 'input'
* Make --disable-input remove all compile-time dependence on X
* Fix EGL support on POSIX to include the symbols
* Change debug protocol to pass types as mangled strings, to make the protocol
usable between clients and filters that weren't built identically
* Makefile fix for parallel make
* TCP/IP remote debugging (still in progress)
* Fix for newer versions of Mesa's GLgl.h

0.0.20080824
------------
* Fix texture viewer

0.0.20080803
------------
* Fix display of program objects
* Make shader/program string querying more robust
* Allow gldb-gui to accept command arguments in Windows
* Fix tracing of OpenGL ES using ubyte or ushort arrays
* Fix display of internalformat parameter in OpenGL ES
* Fix memory corruption in object tracking if objects are deleted
* Update documentation on setting up for Windows and for OpenGL ES
* Prevent porting.h from being included in tarballs

0.0.20080728
------------
* Fix Makefile rules to correctly build gldb-gui on Windows
* Fix generated egl-win.def (builds on Windows may have been broken)
* Implement framebuffer viewing on OpenGL ES

0.0.20080716
------------
* Port to Windows (experimental, don't expect it all to work)
* Port to OpenGL ES 2.0 (VERY experimental, don't expect any of it to work)
* Add alpha filter-set to produce compilable C traces
* Embed a font in the source instead of trying to query it
* Fix some extension tests
* Change CALL to search around aliases until it finds a pointer
* Remove compile-time tests for pre-GL2 extensions
* Fix count for glGetAttachedShaders
* Fix X11 event interception for 32-bit bugle on 64-bit OS (on my box at least)
* Finer-grained modules
* Remove support for older ffmpeg's, and add support for newer ones
* Rename assorted files and symbols
* Other miscellaneous bug-fixes

0.0.20080303
------------
* Fix several bugs in object tracking, which could lead to crashes in
  gldb-gui
* Checking for texture completeness in validate filterset
* Change ifdef tests for GL_EXT_texture_cube_map to GL_ARB_texture_cube_map,
  since the former isn't defined by glext.h
* Force correct version info on glXGetCurrentDisplay
* Convert from inlined GLEE to library GLEW

0.0.20080215
------------
* Fix BUGLE_GL_HAS_EXTENSION_GROUP
* Make PBO test run with a larger choice of extensions
* Fix crash when tracing glXChooseVisual

0.0.20080123
------------
* Fix trace of GL_AMBIENT_AND_DIFFUSE
* Add extra reflection API for querying info about or dumping function
  parameters
* Fix inappropriate aliasing of some extension functions when using NVIDIA
  headers (thanks to Paul Melis for a patch).
* Fix compilation under GTK+ < 2.8

0.0.20080103
------------
* Replace a lot of custom functionality with gnulib
* Change bugle_list_init, bugle_hash_init, bugle_hashptr_init to take a
  destructor function instead of a boolean
* Rename safemem.h to misc.h, since all the safemem functionality got
  subsumed by gnulib
* Eliminated radix tree code in favour of hashptr_table
* Added more documentation on writing filter-sets
* Fixed crash when examining uniforms on ATI
* Fixed display of stats graphs
* Fixed bogus warning about failing to create aux context when GLX < 1.3
* Fixed access to freed memory in stats core code
* Avoid querying state for attributes and uniforms on programs that have
  not been successfully linked
* Move public includes into include/ directory
* Refactor and abstract all the generated tables
* Eliminate ABI dependence on the generated code from the filter API
* Fix potential race conditions with initialisation order
* Some more renaming
* Change CALL_glFoo to CALL(glFoo)
* Rewrite the reflection API for GL extensions
* Merge genexts, genfunctions and gentokens into genpl.perl, with one
  header and one C file.
* Fix several bugs where checking for GL_EXT_foo instead of BUGLE_GL_EXT_foo
* Fix video encoding when width is not a multiple of 4
* Update libswscale when available for video encoding, instead of
  img_convert (which is deprecated)

0.0.20071206
------------
* Fix an int vs. long mismatch
* Update documentation on writing new filter-sets
* Removed old kludge for filter-sets to register space in each call (which
  was non-threadsafe and had potential alignment issues) in favour of
  a per-call object.
* Renamed a lot of types and functions to try to bring a more uniform
  naming to the API.
* Eliminate initialise_hashing in favour of the constructor macros
* Replace some raise()s with bugle_thread_raise()
* Move stats support code into the core and split out modules
* Change the way statslex.l and statsparse.y avoid namespace collisions
  (now more dependent on flex and bison)
* Added About dialog to the debugger
* Use ntohl and htonl in debugger protocol
* Target option in gldb-gui

0.0.20071108
------------
* Fix chunk granularity in generated documentation

0.0.20071107
------------
* Fix segfault if dlopen is called with NULL filename (thanks Ilan Aelion)
* Avoid activating xevent when registering for NoSymbol
* Converted all manual pages and some other documentation to DocBook
* Add DocBook documentation on gldb-gui
* Add support for wildcards in statistics
* Add "calls per frame" statistics
* Add partial support for GCC 4.2
* Fix check for pthread_kill
* Fix bugs in dlopen and interposition regression tests
* Fix shutdown crash if stats_nv is loaded without the NVPerfSDK DLL
* Support non-load ordering dependencies between filter-sets, and use it
  to allow stats_* to be listed after showstats/logstats

0.0.20071009
------------
* Do a fast bypass on functions that are never intercepted
* Updated the benchmarks in the README
* Use a constructor attribute to call initialise_all
* Overload dlopen to better handle engines that dlopen("libGL.so")

0.0.20070718
------------
* Add geometry shader support to the shader viewer
* Fix display of window system framebuffer when an FBO is bound

0.0.20070528
------------
* extoverride filterset
* Rework of the logging system
  - most references to stderr have been replaced by logging
  - option to control the log level
  - new bugle_log_printf helper function and more efficient bugle_log
* trace filterset no longer reports errors (use showerror)
* default filenames are now current directory rather than /tmp, for
  security
* fix gldb crash on systems without transform feedback
* add F8 key for Step in gldb-gui
* update misc bits of documentation
* work around some Mesa bugs

0.0.20070325
------------
* Add incorrectly omitted vendor suffices from extension state
* Add state for GL_EXT_texture_buffer_object
* Add partial state for GL_EXT_bindable_uniform
* Support for GL_EXT_draw_buffers2
* Support for GL_EXT_packed_float
* Support for GL_EXT_draw_instanced
* Support for GL_EXT_texture_shared_exponent
* Support for GL_EXT_framebuffer_sRGB
* Support for GL_EXT_geometry_shader4 (untested)
* Support for GL_EXT_texture_array
* Support for GL_NV_transform_feedback
* Refactor glstate.c to allow callbacks in the middle of a table
* Reorder top-level state to match order in 2.1 spec
* Fix crash-on-exit when using an SDL app and aux contexts
* Fix crash when examining non-square uniform matrices in the debugger

0.0.20070217
------------
* Fix display of ARB program local parameters
* Fix reporting of VBO overrun vs invalid memory
* Fix handling of function aliases in GLX (fixes encapsulation when
  glXGetProcAddress and not glXGetProcAddressARB is used).
* Split type-related functions out of libbugle into libbugleutils
* Communicate state to gldb in raw, not string form
* Display strings in gldb without escaping
* Add extra extensions to genexts.pl
* Add missing CALL_ prefix to multiple calls
* Reduce symbol pollution
* Fix case of programs that define symbols that conflict with OpenGL
* Fix wrapping of GLSL when OpenGL 2.0 headers are not available

0.0.20070107
------------
* Fix display of FBOs on drivers supporting GL_EXT_framebuffer_blit
* Fix crash when using a floating-point PBuffer
* Fix display of per-framebuffer state
* Add an option to show the original frustum in the camera filterset
* Add option to export the current state to XML

0.0.20061227
------------
* Misc tweaks to configure.ac and Makefile.am
* Add missing state GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING
* More verbose reporting from the 'checks' filterset
* Fix sort of columns in the state viewer
* Fix display of GL_INTENSITY textures
* Fix GL_PROGRAM_BINDING_ARB state
* Fix level selection changing to 'Separator' on texture change
* Fix a crash if state cannot be updated
* Deprecated the old screenshot interface to the debugger filterset in
  favour of the more flexible and robust data_framebuffer interface
* Better robustness to pre-GLX 1.3 systems (fixes framebuffer viewer on ATI)
* Added 'remap range' option to image viewers
* Highlight currently bound shaders, textures and framebuffers

0.0.20061110
------------
* Fix the ccache workaround properly

0.0.20061109
------------
* Fix incorrect count for generic attributes in checks filterset
* Work around Mesa bug (#8883) in checks filterset
* Make things work when ccache is in use (thanks to Wolfgang Frisch)
* Fix video capture and screenshot (broken in previous release)
* Fix redefinition of NAN

0.0.20061022
------------
* Rewrite of the statistics engine
  - Configuration file for statistics
  - Statistics from NVPerfSDK
* Rewrite of showstats filterset
  - Opaque background (now readable over a white scene)
  - Faster text rendering via textured quads
  - Aligned layout
  - Graphing
* Reduce GL namespace pollution from internal objects
* Fix some shutdown code including shutdown ordering
* Remove unnecessary include of getopt.h
* Minor improvements in OpenGL 2.1 support

0.0.20060913
------------
* Fix display of various aliased tokens
* Use pkg-config to get libavcodec configuration
* Fix reported names for GL_POINTS and GL_LINES
* Fix some duplicated GL_ARB_imaging state
* Fix spurious errors due to mis-ordering of error and trackbeginend
* Prevent crash when querying state in glBegin/glEnd
* Fix tracing of glReadPixels
* gldb-gui:
  * Work around a bug that caused texture and framebuffer repaints to fail
  * Highlight state changes
  * Options to filter state
  * Option to attach GDB
  * Internal redesign
  * Fix support for GTK+ 2.4 (hopefully)
  * Move breakpoints into a tab
  * Make it possible to disable breakpoints without deleting them
  * Show an appropriate cursor while doing slow updates

0.0.20060828
------------
* Fix framebuffer viewer for texture attachments
* Fix count for glGenQueries/glDeleteQueries

0.0.20060827
------------
* Framebuffer viewer
* Improvements to the texture viewer
* Eliminate double fetch of texture in gldb-gui
* Restore texture binding when not using aux context for texture fetch
* Fix numerous memory leaks in gldb-gui
* Fix some reporting in trace filter-set
* Fix GL_NONE displaying as GL_FALSE in some places
* Added some missing state to the state display

0.0.20060813
------------
* Fix positioning of stats display when resizing the viewport
* Move line numbering out of the text buffer
* Add accumulate/noaccumulate options to showstats
* Improve PBO support e.g. in dumping glTexImage2D
* Show RGBA and UV values in texture viewer
* Support depth and luminance textures in texture viewer
* Misc OpenGL 2.1 stuff e.g. non-square uniform matrices, GL_CURRENT_RASTER_SECONDARY_COLOR
* Update gl2ps to version 1.3.1

0.0.20060528
------------
* Fix break-on-error
* Add flexible log format
* Add support for GL_MAX_RENDERBUFFER_SIZE_EXT.
* Fix false warnings when glMultiTexCoord* is called from inside
  begin/end.
* Add support for the "step" operation to gldb and gldb-gui.
* Fix numerous shutdown bugs
* Fix bug in the showextensions filterset revealed by the fix above
* Create a separate manual page for each filter-set.

0.0.20060429
------------
* Fix a nasty bug in generator that corrupted the type tables, leading to
  a crash when logging glMultMatrixf

0.0.20060416
------------
* Add 'camera' filterset
* Add --disable-xevent option to configure to handle the case where
  ltdl fails to get symbols from libX11

0.0.20060306
------------
* Fix compilation problem with newer versions of flex
* Fix some Debian testing build problems (thanks to James Lyon for a patch)

0.0.20060224
------------
* Fix numerous C89 warnings. Unfortunately GLee is not valid C89 code.
* Fix dumping of return from glGetProgramStringARB
* Change the way pages were refreshed to be cleaner and to work on GTK+ 2.8.
* Fix bogus warnings about glVertexAttrib*ARB being called from outside
  glBegin/glEnd with indices other than 0
* Pass textures to gldb-gui in GL_FLOAT, in preparation for eventual
  tone mapping
* Heavy modification of the filter load/unload/activate/deactivate code.
  Filtersets are now loaded on startup and never unloaded, but can
  be activated or deactivated on the fly by the debugger or by keyboard
  shortcut.
* Keyboard interception
* Make video capture work with pre-release versions of libavformat
* Make wireframe and frontbuffer work with activation and deactivation
* Integrate gl2ps to replace epswire
* Change license to GPLv2 only

0.0.20060101
------------
* gldb-gui improvements
  - Fix programs hanging around and spinning after gldb-gui quits
  - Convert values to UTF8 (TODO: names as well)
  * Texture viewer improvements
    - copy button (can paste into GIMP)
    - display of 1D, 2D, RECT and cubemap textures
    - control over mag and min filters
    - fit to window or choice of zoom levels
    - work around for ATI driver bug
* Rewrite of the GLSL state tracking
* Add bugle_hash_count and bugle_hashptr_count to simplify hash table class
* Allow aux contexts to be created in absence of GLX 1.3
* Make GL_EXT_texture_rectangle support work even if neither
  GL_NV_texture_rectangle nor GL_ARB_texture_rectangle is advertised
* Use glXGetProcAddress to get function pointers rather than libtool
  (ATI driver works much better now)
* test suite:
  - Use GLee rather than relying on GL_GLEXT_PROTOTYPES
  - Fix some failures in caused by driver weirdness not bugle bugs
  - Rewrite the log comparison tool to give more useful feedback
  - Added a test that just creates textures, to test the texture viewer

0.0.20051112
------------
* Fix find_header.pl to look in . and in $srcdir
* Fix Perl warning in glexts.perl
* Have genfunctions.perl spit out #warnings in the C++ code when
  the function lists mismatch, rather than breaking everything
* Fix a check for the incorrect symbol in glstate.c (broke with
  older glext.h)
* Add support for several extensions in the state manager:
  - GL_ATI_draw_buffers
  - GL_ARB_vertex_program
  - GL_ARB_fragment_program
  - GL_EXT_texture_filter_anisotropic
  - GL_EXT_depth_bounds_test
  - GL_NV_texture_rectangle/GL_EXT_texture_rectangle/GL_ARB_texture_rectangle
  - GL_NV_light_max_exponent
  - GL_NV_depth_clamp
  - GL_NV_multisample_filter_hint
  - GL_NV_texture_expand_normal
  - GL_IBM_rasterpos_clip
  - GL_EXT_framebuffer_object (incomplete)
* Add support for textures beyond GL_MAX_TEXTURE_UNITS
  i.e. GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS and GL_MAX_TEXTURE_COORDS
* Add GL_COMPRESSED_TEXTURE_FORMATS to the state
* Extend the extension generator to handle extension groups
* Add some extra checks to the 'checks' filterset
* Add documentation on extension handling
* gldb no longer hangs when asked for non-existent substate
* gldb gives all lines of backtrace, not just first line
* split gldb-common.c out from gldb.c to facilitate gldb-gui
* early work on gldb-gui
* fix gldb segfault on program exit

0.0.20050221
------------
* Added checks filterset
* Vastly improved support for systems short on extensions
* Changed the way tests are done (using regexes) to make them more
  robust and less likely to fail when moving to a different system.
* Redesign of the filter management code to reduce overhead.
* Redesign of the filter-set variable code to use tables rather than
  banks of if's.
* Rewrite some of the documentation.
* Rewrite of the code generator; now generates GROUP_ tokens and
  generally separates groups from functions.
* Rewrite of the state manager (incomplete).
* Support for GLSL.
* Rewritten object tracker, using radix trees.
* Linked lists and hash tables are now told at creation time whether
  they own their memory.
* Make opaque bugle_object and bugle_object_view typedefs.
* Redo the internals of object layer storage to avoid possible
  alignment problems.
* Added a threading abstraction layer.
* Removed canon.c/canon.h, since they are no longer needed.
* State now assembled by gldb, allowing tab completion for state
* Switch to ltdl for module and library loading

0.0.20041123
------------
* Added stats and showstats filtersets
* Speeded up the case where functions are not intercepted at all

0.0.20041108
------------
* Fix crash in video capture (not sure how it ever worked)
* Fix dumping bug (wrong field was being type overridden)
* (gldb) Make a blank line rerun previous command
* Fix various compiler warnings
* Added --without-lavc configure option
* Add the showextensions filter-set.

0.0.20041025
------------
* Redo libreadline detection to fall back gracefully if the library
  doesn't link properly, and to explicitly link against libncurses if
  present (needed for Slackware with readline 5, apparently)
* Better support for older versions of glext.h, as well as better support
  for possible future versions where extensions get promoted to core.
* Better dumping of GLSLang functions (GetUniformARB needs works still).
* Fix interception of glXGetProcAddressARB (was not loading the filter)

0.0.20041011
------------
* (gldb) Allow options to be passed to the program
* (gldb) screenshot command
* (gldb) Enable and disable filters on the fly
* (capture) By default, skip or duplicate frames for videos
* Fold old types.c and types.h into utils.c and utils.h
* Introduce names.c and names.h, to hold just the names of the functions
* Rewrite the token capture system, which now captures extension info
* New system to capture which functions belong to which extensions
* Support for per-context, per-filter state
* Move tracker library into the core source
* Move logging into the core source, and split the tracing functionality
  out into a 'trace' module
* Make gldb and libbugleutils independent of GL and X
* Hex output of GLXDrawable (looks nicer, plus removes spurious regression
  errors)

0.0.20040903
------------
* Improvements to video capture: get libavcodec to do the mirroring,
  and use GL_EXT_pixel_buffer_object for possibly faster capture.

0.0.20040719
------------
* Added ability to stop running program with Ctrl-C.
* Improved thread safety.
* Rewrite of the state code
* Added basic state dump support to gldb
* Dump overrides are now boolean expressions, not functions
* Improved test suite, with some log regression tests
* Support for aux contexts
* Added movie mode to screenshot filterset

0.0.20040614
------------
* Added the gldb debugger
* Added some sanity checks to make sure that internal code does not generate
  GL errors.
* Remove the "trap" option of the "error" module.
* Autoload the invoke filterset, and load the debugger filterset if the
  environment variables are set.
* Wrote manual pages.

0.0.20040609
------------
* Made lexer.ll more robust to headers containing function bodies and
  inline assembler.

0.0.20040608
------------
* First public release