How can I debug GLSL shaders? When writing non-trivial shaders (just as when writing any other piece of non-trivial code), people make mistakes.[citation needed] However, I can't just debug it like any other code - you can't just attach gdb or the Visual Studio debugger after all. You can't even do printf debugging, because there's no form of console output. What I usually do is render the data I want to look at as colour, but that is a very rudimentary and amateurish solution. I'm sure people have come up with better solutions.

So how can I actually debug a shader? Is there a way to step through a shader? Can I look at the execution of the shader on a specific vertex/primitive/fragment?

(This question is specifically about how to debug shader code akin to how one would debug "normal" code, not about debugging things like state changes.)
As far as I know there are no tools that allows you to steps through code in a shader (also, in that case you would have to be able to select just a pixel/vertex you want to &quot;debug&quot;, the execution is likely to vary depending on that).
(NOTE: Renderdoc allows you to do so by selecting a specific thread/pixel)
What I personally do is a very hacky &quot;colourful debugging&quot;. So I sprinkle a bunch of dynamic branches with #if DEBUG / #endif guards that basically say
#if DEBUG
if( condition ) 
    outDebugColour = aColorSignal;
#endif

.. rest of code .. 

// Last line of the pixel shader
#if DEBUG
OutColor = outDebugColour;
#endif

So you can &quot;observe&quot; debug info this way. I usually do various tricks like lerping or blending between various &quot;colour codes&quot; to test various more complex events or non-binary stuff.
In this &quot;framework&quot; I also find useful to have a set of fixed conventions for common cases so that if I don't have to constantly go back and check what colour I associated with what.
The important thing is have a good support for hot-reloading of shader code, so you can almost interactively change your tracked data/event and switch easily on/off the debug visualization.
If need to debug something that you cannot display on screen easily, you can always do the same and use one frame analyser tool to inspect your results. I've listed a couple of them as answer of this other question.
Obv, it goes without saying that if I am not &quot;debugging&quot; a pixel shader or compute shader, I pass this &quot;debugColor&quot; info throughout the pipeline without interpolating it (in GLSL with  flat  keyword )
Again, this is very hacky and far from proper debugging, but is what I am stuck with not knowing any proper alternative.