(Define a macro to) facilitate OpenGL command debugging? - c++

Sometimes it takes a long time of inserting conditional prints and checks to glGetError() to narrow down using a form of binary search where the first function call is that an error is first reported by OpenGL.
I think it would be cool if there is a way to build a macro which I can wrap around all GL calls which may fail which will conditionally call glGetError immediately after. When compiling for a special target I can have it check glGetError with a very high granularity, while compiling for typical release or debug this wouldn't get enabled (I'd check it only once a frame).
Does this make sense to do? Searching for this a bit I find a few people recommending calling glGetError after every non-draw gl-call which is basically the same thing I'm describing.
So in this case is there anything clever that I can do (context: I am using GLEW) to simplify the process of instrumenting my gl calls this way? It would be a significant amount of work at this point to convert my code to wrap a macro around each OpenGL function call. What would be great is if I can do something clever and get all of this going without manually determining which are the sections of code to instrument (though that also has potential advantages... but not really. I really don't care about performance by the time I'm debugging the source of an error).

Try this:
void CheckOpenGLError(const char* stmt, const char* fname, int line)
{
GLenum err = glGetError();
if (err != GL_NO_ERROR)
{
printf("OpenGL error %08x, at %s:%i - for %s\n", err, fname, line, stmt);
abort();
}
}
#ifdef _DEBUG
#define GL_CHECK(stmt) do { \
stmt; \
CheckOpenGLError(#stmt, __FILE__, __LINE__); \
} while (0)
#else
#define GL_CHECK(stmt) stmt
#endif
Use it like this:
GL_CHECK( glBindTexture2D(GL_TEXTURE_2D, id) );
If OpenGL function returns variable, then remember to declare it outside of GL_CHECK:
const char* vendor;
GL_CHECK( vendor = glGetString(GL_VENDOR) );
This way you'll have debug checking if _DEBUG preprocessor symbol is defined, but in "Release" build you'll have just the raw OpenGL calls.

BuGLe sounds like it will do what you want:
Dump a textual log of all GL calls made.
Take a screenshot or capture a video.
Call glGetError after each call to check for errors, and wrap glGetError so that this checking is transparent to your program.
Capture and display statistics (such as frame rate)
Force a wireframe mode
Recover a backtrace from segmentation faults inside the driver, even if the driver is compiled without symbols.

Related

Where can I see ATLTRACE output?

I'm maintaining a C++ COM project. There are some trace lines like ATLTRACE(message);
I searched ATLTRACE. MSDN told Visual C++ output window will display it. However, the product is a release one. The customer won't have the source nor to debug it in VS. So is there any other convenient way to see it? Will Windows Event viewer catch that? Or I have to change the code? Win7, VS2013
The ATLTRACE only uses only the debug output and it works only in the Debug version!
So you may give the enduser a debug version for testing purpose, and use DebugView from Sysinternals. But this may be complicated because you also have to over the debug runtimes that are not redistributable.
But you can easily write your own MY_TRACE macro that has the same functionality.
#define MY_TRACE GetMyTracer() // returns object of CMyTracer
...
class CMyTracer
{
...
// Helper operator to get the trace commands. They call the TraceV functions
void operator()(PCSTR pszFormat, ...);
void operator()(PCWSTR pszFormat, ...);
// Worker functions that do the real job calling TraceV functions
void Trace(PCSTR pszFormat, ...);
void Trace(PCWSTR pszFormat, ...);
// Allowed to be virtual to do some internal mystique stuff, like redirecting and this functions perform all output...
virtual void TraceV(PCSTR pszFormat, va_list args);
virtual void TraceV(PCWSTR pszFormat, va_list args);
...
Now you can use this instead of ATLTRACE
...
MYTRACE("Simple output\n");
MYTRACE("More complex output %d\n", 4711);
Note: It is not wise to replace all ATLTRACE macros with your own replacement. You may spread your trace output onto locations were it don't have impact un speed, but is worth the information.
ATLTRACE is a macro that compiles to nothing in a release build. You'll need to rebuild the project with the _DEBUG macro defined (see <atltrace.h>) to get those to display. However, output generated by ATLTRACE is a debug output string, and will typically only display in the debugger's output window.
If there is important information you need, and if it is in code you control, you'll be better off changing the ATLTRACE macro usage to something else, to either log to the event log or a log file the customer can send to you.
As mentioned by 1201ProgramAlarm, release builds of ATL projects have ATLTRACE macros evaluated to nothing and the binary has no real code generated for respective source code lines. That is, you cannot see the output without altering source code.
In order to not alter the project much, you can redefine the tracing macro itself and produce release build with tracing capabilities where output is routed as defined by you, for example to standard debug output using OutputDebugString API.
See:
How to enable the TRACE macro in Release mode?
AtlReleaseTrace

glewInit() crashing (segfault) after creating osmesa (off-screen mesa) context

I'm trying to run an opengl application on a remote computing cluster. I'm using osmesa as I intend to execute off-screen software rendering (no x11 forwarding etc). I want to use glew (to make life dealing with shaders and other extension related calls easier), and I seem to have built and linked both mesa and glew fine.
When I call mesa-create-context, glewinit gives a OPENGL Version not available output, which probably means the context has not been created. When I call glGetString(GL_EXTENSIONS) i dont get any output, which confirms this. This also shows that glew is working fine on its own. (Other glew commands like glew version etc also work).
Now when I (as shown below), add the mesa-make-context-current function, glewinit crashes with a segfault. Running glGetString(GL_EXTENSIONS) gives me a list of extensions now however (which means context creation is successful!)
I've spent hours trying to figure this out, tried tinkering but nothing works. Would greatly appreciate any help on this. Maybe some of you has experienced something similar before?? Thanks again!
int Height = 1; int Width = 1;
OSMesaContext ctx; void *buffer;
ctx = OSMesaCreateContext( OSMESA_RGBA, NULL );
buffer = malloc( Width * Height * 4 * sizeof(GLfloat) );
if (!OSMesaMakeCurrent( ctx, buffer, GL_UNSIGNED_BYTE, Width, Height )) {
printf("OSMesaMakeCurrent failed!\n");
return 0;
}
-- glewinit() crashes after this.
Just to add, osmesa and glew actually did not compile initially. Because glew undefines GLAPI in it's last line and since osmesa will not include gl.h again, GLAPI remains undefined and causes an error in osmesa.h (119). I got around this by adding an extern to GLAPI, not sure if this is relevant though.
Looking at the source to glewInit in glew.c if glewContextInit succeeds it returns GLEW_OK, GLEW_OK is defined to 0, and so on Linux systems it will always call glxewContextInit which calls glX functions that in the case of OSMesa will likely not be ready for use. This will cause a segfault (as I see), and it seems that the glewInit function has no capability to handle this case unfortunately without patching the C source and recompiling the library.
If others have already solved this I would be interested, I have seen some patched versions of the glew.c sources that workaround this. It isn't clear if there is any energy in the GLEW community to merge changes in that address this use case.

Checking and closing HANDLE

I am working with HANDLES, the first one, nextColorFrameEvent is an event handler and the second one is a stream handler. They are being initialized in the following piece of code:
nextColorFrameEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
hr = nui->NuiImageStreamOpen(
NUI_IMAGE_TYPE_COLOR,
NUI_IMAGE_RESOLUTION_640x480,
0,
2,
nextColorFrameEvent,
&videoStreamHandle);
I want to properly deal with them on destruction, while not creating errors at the same time. Sometimes the initializer wont be called, so both HANDLEs are still NULL when the software comes to an end. Thats why I want to check first if the HANDLEs are properly initialized etc. and if they are, I want to close them. I got my hands on the following piece of code for this:
if (nextColorFrameEvent && nextColorFrameEvent != INVALID_HANDLE_VALUE)CloseHandle(nextColorFrameEvent);
#ifdef QT_DEBUG
DWORD error = GetLastError();
qDebug()<< error;
#endif
if (videoStreamHandle && videoStreamHandle != INVALID_HANDLE_VALUE)CloseHandle(videoStreamHandle);
#ifdef QT_DEBUG
error = GetLastError();
qDebug()<< error;
#endif
But this is apperently incorrect: if I do not run the initializer and then close the software this piece of code runs and gives me a 6:
Starting C:\...\Qt\build-simpleKinectController-Desktop_Qt_5_0_2_MSVC2012_64bit-Debug\debug\simpleKinectController...
6
6
C:\...\Qt\build-simpleKinectController-Desktop_Qt_5_0_2_MSVC2012_64bit-Debug\debug\simpleKinectController exited with code 0
which means:
ERROR_INVALID_HANDLE 6 (0x6) The handle is invalid.
Which means that closeHandle ran anyway despite the tests. What tests should I do to prevent closing when the handle is not a valid HANDLE?
Bonus question: if I run the initializer this error will no longer appear when only closing colorFrameEvent, but will still appear when closing videoStreamHandle:
Starting C:\...\Qt\build-simpleKinectController-Desktop_Qt_5_0_2_MSVC2012_64bit-Debug\debug\simpleKinectController...
0
6
C:\...\Qt\build-simpleKinectController-Desktop_Qt_5_0_2_MSVC2012_64bit-Debug\debug\simpleKinectController exited with code 0
Do I need a diffent function to close a stream handler?
nui->NuiImageStreamOpen(...) does not create a valid Windows handle for the stream but instead it creates an internal handle inside the driver side.
So you can not use windows API to release/close stream handle !!!
To do that just call nui->NuiShutdown(). I have not yet used the callback event but I think its a valid windows handle and should be closed normally.
if you need just to change settings you can always call nui->NuiImageStreamOpen(...) with new settings. No need to shutdown ...
I would also welcome function nui->NuiImageStreamClose(...); because current state of API complicates things for long term running aps with changing sensor configurations.
CreateEvent (http://msdn.microsoft.com/en-us/library/windows/desktop/ms682396(v=vs.85).aspx) returns NULL if an event was not created.
You are checking against INVALID_HANDLE_VALID which is not NULL.
You are probably trying to double-close a handle. That is likely to generate ERROR_INVALID_HANDLE 6. You can't detect this with your test, because the first CloseHandle(nextColorFrameEvent); did not change nextColorFrameEvent.
The solution is to use C++ techniques, in particular RAII. There are plenty of examples around how to use shared_ptr with HANDLE. shared_ptr is the standard solution to run cleanup code at most once, after everyone is done, and only if anybody actually allocated a resource.
there is a good way of debugging that I'm particularly fond of, despite being all writen in macros, which are nasty, but in this case they work wonders.
Zed's Awesome Debug Macros
there are a couple of things I like to change though. They make extensive use of goto, which I tend to avoid, specially in c++ projects, because otherwise you wouldn't be able to declare variables mid-code. This is why I use exit(-1) instead, or, in some projects, I mod the code to try, throw, catch c++. Since you are working with Handles, a good thing would be setting a variable and telling the program to close itself.
here is what I mean. Take this piece of code from the macros (i assume you would read the exercise and familiarize with the macros):
#define check(A, M, ...) if(!(A)) { log_err(M, ##__VA_ARGS__); errno=0; goto error; }
i'd change
goto error;
to something like
error = true;
the syntax inside the program would be something like, and I took it from a multithread program I'm writing myself:
pRSemaphore = CreateSemaphore(NULL, 0, MAX_TAM_ARQ, (LPCWSTR) "p_read_semaphore");
check(pRSemaphore, "Impossible to create semaphore: %d\n", GetLastError());
As you can see, GetLastError is only called when pRSemaphore is set to null. There are somewhat fancy mechanisms behind the macro (at least they are fancy for me), but they are hidden inside the "check" mask, so you needn't worry about them.
next step is to treat the error with something like:
inline void ExitWithError(bool &err) {
//close all handles
//tell other related process to do the same if necessary
exit(-1);
}
or you could just call it inside the macro like
#define check(A, M, ...) if(!(A)) { log_err(M, ##__VA_ARGS__); errno=0; ExitWithError(); }
hope I could be of any help

CUDA cudaMalloc

I've started writing a new CUDA application. However I hit a funny detour along the way.
Calling the first cudaMalloc on a variable x, fails the first time. However when I call it the second time it returns cudaSuccess. Recently upgraded to CUDA 4.0 SDK, it's a really weird bug.
I even did some testing and it seems the first call of cudaMalloc fails.
The very first call to any of the cuda library functions launches an initialisation subroutine. It can happen that somehow the initialisation fails and not the cudaMalloc itself. (CUDA Programming Guide, section 3.2.1)
Somehow, later, however it seems it works, despite the initial failure. I don't know your setting and your code so I can't really help you further. Check the Programming Guide!
I would strongly recommend using the CUDA_SAFE_CALL macro if you aren't -- to force the thread synchronisation, at least while you're debugging the code:
CUDA_SAFE_CALL(cudaMalloc((void**) &(myVar), mem_size_N ));
Update: As per #talonmies, you don't need the cutil library. So let's rewrite the solution:
/* Allocate Data */
cudaMalloc((void**) &(myVar), mem_size_N );
/* Force Thread Synchronization */
cudaError err = cudaThreadSynchronize();
/* Check for and display Error */
if ( cudaSuccess != err )
{
fprintf( stderr, "Cuda error in file '%s' in line %i : %s.\n",
__FILE__, __LINE__, cudaGetErrorString( err) );
}
And as noted in the other answer -- you may want to include the synch & check before you allocation memory just to make sure the API initialized correctly.

What is the best way to debug OpenGL? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 27 days ago.
The community is reviewing whether to reopen this question as of 27 days ago.
Improve this question
I find that a lot of the time, OpenGL will show you it failed by not drawing anything. I'm trying to find ways to debug OpenGL programs, by inspecting the transformation matrix stack and so on. What is the best way to debug OpenGL? If the code looks and feels like the vertices are in the right place, how can you be sure they are?
There is no straight answer. It all depends on what you are trying to understand. Since OpenGL is a state machine, sometimes it does not do what you expect as the required state is not set or things like that.
In general, use tools like glTrace / glIntercept (to look at the OpenGL call trace), gDebugger (to visualize textures, shaders, OGL state etc.) and paper/pencil :). Sometimes it helps to understand how you have setup the camera and where it is looking, what is being clipped etc. I have personally relied more to the last than the previous two approaches. But when I can argue that the depth is wrong then it helps to look at the trace. gDebugger is also the only tool that can be used effectively for profiling and optimization of your OpenGL app.
Apart from this tool, most of the time it is the math that people get wrong and it can't be understood using any tool. Post on the OpenGL.org newsgroup for code specific comments, you will be never disappointed.
What is the best way to debug OpenGL?
Without considering additional and external tools (which other answers already do).
Then the general way is to extensively call glGetError(). However a better alternative is to use Debug Output (KHR_debug, ARB_debug_output). This provides you with the functionality of setting a callback for messages of varying severity level.
In order to use debug output, the context must be created with the WGL/GLX_DEBUG_CONTEXT_BIT flag. With GLFW this can be set with the GLFW_OPENGL_DEBUG_CONTEXT window hint.
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE);
Note that if the context isn't a debug context, then receiving all or even any messages aren't guaranteed.
Whether you have a debug context or not can be detected by checking GL_CONTEXT_FLAGS:
GLint flags;
glGetIntegerv(GL_CONTEXT_FLAGS, &flags);
if (flags & GL_CONTEXT_FLAG_DEBUG_BIT)
// It's a debug context
You would then go ahead and specify a callback:
void debugMessage(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length,
const GLchar *message, const void *userParam)
{
// Print, log, whatever based on the enums and message
}
Each possible value for the enums can be seen on here. Especially remember to check the severity, as some messages might just be notifications and not errors.
You can now do ahead and register the callback.
glEnable(GL_DEBUG_OUTPUT);
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
glDebugMessageCallback(debugMessage, NULL);
glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, NULL, GL_TRUE);
You can even inject your own messages using glDebugMessageInsert().
glDebugMessageInsert(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0,
GL_DEBUG_SEVERITY_NOTIFICATION, -1, "Vary dangerous error");
When it comes to shaders and programs you always want to be checking GL_COMPILE_STATUS, GL_LINK_STATUS and GL_VALIDATE_STATUS. If any of them reflects that something is wrong, then additionally always check glGetShaderInfoLog() / glGetProgramInfoLog().
GLint linkStatus;
glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
if (!linkStatus)
{
GLchar *infoLog = new GLchar[infoLogLength + 1];
glGetProgramInfoLog(program, infoLogLength * sizeof(GLchar), NULL, infoLog);
...
delete[] infoLog;
}
The string returned by glGetProgramInfoLog() will be null terminated.
You can also go a bit more extreme and utilize a few debug macros in a debug build. Thus using glIs*() functions to check if the expected type is the actual type as well.
assert(glIsProgram(program) == GL_TRUE);
glUseProgram(program);
If debug output isn't available and you just want to use glGetError(), then you're of course free to do so.
GLenum err;
while ((err = glGetError()) != GL_NO_ERROR)
printf("OpenGL Error: %u\n", err);
Since a numeric error code isn't that helpful, we could make it a bit more human readable by mapping the numeric error codes to a message.
const char* glGetErrorString(GLenum error)
{
switch (error)
{
case GL_NO_ERROR: return "No Error";
case GL_INVALID_ENUM: return "Invalid Enum";
case GL_INVALID_VALUE: return "Invalid Value";
case GL_INVALID_OPERATION: return "Invalid Operation";
case GL_INVALID_FRAMEBUFFER_OPERATION: return "Invalid Framebuffer Operation";
case GL_OUT_OF_MEMORY: return "Out of Memory";
case GL_STACK_UNDERFLOW: return "Stack Underflow";
case GL_STACK_OVERFLOW: return "Stack Overflow";
case GL_CONTEXT_LOST: return "Context Lost";
default: return "Unknown Error";
}
}
Then checking it like this:
printf("OpenGL Error: [%u] %s\n", err, glGetErrorString(err));
That still isn't very helpful or better said intuitive, as if you have sprinkled a few glGetError() here and there. Then locating which one logged an error can be troublesome.
Again macros come to the rescue.
void _glCheckErrors(const char *filename, int line)
{
GLenum err;
while ((err = glGetError()) != GL_NO_ERROR)
printf("OpenGL Error: %s (%d) [%u] %s\n", filename, line, err, glGetErrorString(err));
}
Now simply define a macro like this:
#define glCheckErrors() _glCheckErrors(__FILE__, __LINE__)
and voila now you can call glCheckErrors() after everything you want, and in case of errors it will tell you the exact file and line it was detected at.
GLIntercept is your best bet. From their web page:
Save all OpenGL function calls to text or XML format with the option to log individual frames.
Free camera. Fly around the geometry sent to the graphics card and enable/disable wireframe/backface-culling/view frustum render
Save and track display lists.
Saving of the OpenGL frame buffer (color/depth/stencil) pre and post render calls. The ability to save the "diff" of pre and post images is also available.
Apitrace is a relatively new tool from some folks at Valve, but It works great! Give it a try: https://github.com/apitrace/apitrace
I found you can check using glGetError after every line of code your suspect will be wrong, but after do it, the code looks not very clean but it works.
For those on Mac, the buit in OpenGL debugger is great as well. It lets you inspect buffers, states, and helps in finding performance issues.
The gDebugger is an excellent free tool, but no longer supported. However, AMD has picked up its development, and this debugger is now known as CodeXL. It is available both as a standalone application or as a Visual Studio plugin - works both for native C++ applications, or Java/Python applications using OpenGL bindings, both on NVidia and AMD GPUs. It's one hell of a tool.
There is also the free glslDevil: http://www.vis.uni-stuttgart.de/glsldevil/
It allows you to debug glsl shaders extensively. It also shows failed OpenGL calls.
However it's missing features to inspect textures and off screen buffers.
Nsight is good debugging tool if you have an NVidia card.
Download and install RenderDoc.
It will give you a timeline where you can inspect the details of every object.
Use glObjectLabel to give OpenGL objects names. These will show up in RenderDoc.
Enable GL_DEBUG_OUTPUT and use glDebugMessageCallback to install a callback function. Very verbose but you won't miss anything.
Check glGetError at the end of every function scope. This way, you will have a traceback to the source of a OpenGL error in the function scope where the error occurred. Very maintainable. Preferably, use a scope guard.
I don't check errors after each OpenGL call unless there's a good reason for it. For example, if glBindProgramPipeline fails that is a hard stop for me.
You can find out even more about debugging OpenGL here.
Updating the window title dynamically is convenient for me.
Example (use GLFW, C++11):
glfwSetWindowTitle(window, ("Now Time is " + to_string(glfwGetTime())).c_str());