gummybears/opengl_with_crystal

Problem raising error in load_shader

Opened this issue · 3 comments

First of all, thanks a lot for this effort and repository.

I am quite new to Crystal.

I have found out that when the compile status of a shader is false and LibGL.get_shader_info_log is used to get information about the error, instead of raising the error as the code purports to do, an invalid memory access occurs.

I discovered this when I missed a semicolon at the end of a shader statement.

The code I am referring to is this:

if compile_status == LibGL::FALSE
        LibGL.get_shader_info_log(shader_id, 2048, nil, out compile_log)
        compile_log_str = String.new(pointerof(compile_log))
        compile_error_code = LibGL.get_error
        raise "Error #{compile_error_code}: Failed compiling shader.\n'#{text}': #{compile_log_str}"
end

Possibly the string to hold the compile log is too small. What happens if
you double it like

LibGL.get_shader_info_log(shader_id, 2*2048, nil, out compile_log)

The problem persists. Actually I did try that out. Here is the relevant code and output:

if compile_status == LibGL::FALSE
        LibGL.get_shader_info_log(shader_id, 2048, nil, out compile_log)
        compile_log_str = String.new(pointerof(compile_log))
        compile_error_code = LibGL.get_error
        puts "Error compiling shader"
        puts text
        puts compile_log_str
        puts "Aborting"
        #exit 1
        raise "Error #{compile_error_code}: Failed compiling shader.\n'#{text}': #{compile_log_str}"
end

Output:

Error compiling shader
#version 410

in vec3 vp
void main() {
  gl_Position = vec4(vp, 1.0);
}
0:4(1): error: syntax error, unexpected VOID_TOK, expecting ',' or ';'
Aborting
Invalid memory access (signal 11) at address 0x0
[0x562c03ea1946] *Exception::CallStack::print_backtrace:Nil +118 in ./bin/anton_0
[0x562c03e8f596] ~procProc(Int32, Pointer(LibC::SiginfoT), Pointer(Void), Nil) +310 in ./bin/anton_0
[0x7fef3283bcf0] ?? +140665321405680 in /lib/x86_64-linux-gnu/libc.so.6
[0x7fef32b9dc1e] ?? +140665324952606 in /lib/x86_64-linux-gnu/libgcc_s.so.1
[0x7fef32b9f97b] _Unwind_Backtrace +187 in /lib/x86_64-linux-gnu/libgcc_s.so.1
[0x562c03e96a9b] *Exception::CallStack::unwind:Array(Pointer(Void)) +91 in ./bin/anton_0
[0x562c03e96a2a] *Exception::CallStack#initialize:Array(Pointer(Void)) +10 in ./bin/anton_0
[0x562c03e96a08] *Exception::CallStack::new:Exception::CallStack +40 in ./bin/anton_0
[0x562c03e8002f] *raise<Exception>:NoReturn +63 in ./bin/anton_0
[0x562c03e7ffee] ?? +94747044085742 in ./bin/anton_0
fish: Job 1, './bin/anton_0' terminated by signal SIGSEGV (Address boundary error)

If I replace the raise statement by an exit 1 it is ok.

I am on Ubuntu 22.10. and Crystal version 1.11.2.

I think I have found a solution. We have to explicitly create the log string.

if compile_status == LibGL::FALSE
        compile_log = Array.new(2048, ' ').join
        LibGL.get_shader_info_log(shader_id, 2048, nil, compile_log.to_unsafe)
        compile_error_code = LibGL.get_error
        raise "Error #{compile_error_code}: Failed compiling shader.\n'#{text}': #{compile_log}"
end

This works as expected.