go-gl/example

Go 1.6 -msan option error (memory sanitizer)

Closed this issue · 6 comments

I just tried to run gl21 example with the new -msan option and it gives error (other projects give the same error)


==18024==WARNING: MemorySanitizer: use-of-uninitialized-value
#0 0x7a2877 (/tmp/go-build517668219/command-line-arguments/_obj/exe/cube+0x7a2877)
#1 0x793e3c (/tmp/go-build517668219/command-line-arguments/_obj/exe/cube+0x793e3c)
#2 0x78a7ff (/tmp/go-build517668219/command-line-arguments/_obj/exe/cube+0x78a7ff)
#3 0x51f3cf (/tmp/go-build517668219/command-line-arguments/_obj/exe/cube+0x51f3cf)


The command was:
$ CC=clang-3.8 go run -v -msan cube.go

go 1.6
clang 3.8
llvm 3.8
ubuntu 16.04

Should it even work or not?
I have (almost) no other problems with these bindings. Just curious.

use-of-uninitialized-value

Is it possible to see which lines of code, or variable names it's referring to?

@shurcooL

I can't test it right now.
For me its a non-issue currently, but i think it could be a bug or something.
Maybe someone else can test this in future.

It looks like -msan flag is Linux only:

https://github.com/golang/go/blob/go1.6.2/src/runtime/msan/msan.go#L5

So someone with Linux would need to look into it.

Tested on Ubuntu 16.04.

I can reproduce this here. Here is a go tool objdump run on the binary. dump.gz

==31406==WARNING: MemorySanitizer: use-of-uninitialized-value
    #0 0x6ff345  (/home/pwaller/.local/src/github.com/go-gl/examples/gl41core-cube/gl41core-cube+0x6ff345)
    #1 0x6ed1dd  (/home/pwaller/.local/src/github.com/go-gl/examples/gl41core-cube/gl41core-cube+0x6ed1dd)
    #2 0x71b91f  (/home/pwaller/.local/src/github.com/go-gl/examples/gl41core-cube/gl41core-cube+0x71b91f)
    #3 0x4f06cf  (/home/pwaller/.local/src/github.com/go-gl/examples/gl41core-cube/gl41core-cube+0x4f06cf)

SUMMARY: MemorySanitizer: use-of-uninitialized-value (/home/pwaller/.local/src/github.com/go-gl/examples/gl41core-cube/gl41core-cube+0x6ff345) 

#0 is the msan crash thunk. #1 is glfwInit, #2 is _cgo_4c81a0848e0b_Cfunc_glfwInit but the stack return address appears to be one byte short of an instruction.

        :0      0x6ed19f        0f842c020000                    JE 0x6ed3d1                                             
        :0      0x6ed1a5        41bf01000000                    MOVL $0x1, R15                                          
        :0      0x6ed1ab        85c0                            TESTL AX, AX                                            
        :0      0x6ed1ad        0f85fe010000                    JNE 0x6ed3b1                                            
        :0      0x6ed1b3        4c8d256e398902                  LEAQ 0x289396e(IP), R12                                 
        :0      0x6ed1ba        31f6                            XORL SI, SI                                             
        :0      0x6ed1bc        baa80d0000                      MOVL $0xda8, DX                                         
        :0      0x6ed1c1        4c89e7                          MOVQ R12, DI                                            
        :0      0x6ed1c4        e84790d7ff                      CALL __msan_memset(SB)                                  
        :0      0x6ed1c9        4c8b2d908d3e00                  MOVQ 0x3e8d90(IP), R13                                  
        :0      0x6ed1d0        6441c7450000000000              FS MOVL $0x0, FS:0(R13)                                 
        :0      0x6ed1d9        e8a2db0000                      CALL _glfwPlatformInit(SB)                              
        :0      0x6ed1de        64418b4d00                      FS MOVL FS:0(R13), CX                                   
        :0      0x6ed1e3        85c9                            TESTL CX, CX                                            
        :0      0x6ed1e5        740a                            JE 0x6ed1f1                                             
        :0      0x6ed1e7        f7d1                            NOTL CX                                                 
        :0      0x6ed1e9        21c1                            ANDL AX, CX                                             
        :0      0x6ed1eb        0f84e5010000                    JE 0x6ed3d6                                             
        :0      0x6ed1f1        85c0                            TESTL AX, AX                                            
        :0      0x6ed1f3        0f8463010000                    JE 0x6ed35c                                             
        :0      0x6ed1f9        488b05f88d3e00                  MOVQ 0x3e8df8(IP), AX      

Unfortunately, I can't reproduce this with plain-old-c. In a subdirectory of the cube example I did the following, compiling glfw in the same way that go does, from sources shipped with the go glfw package.

clang-3.8 \
 -fsanitize=address \
 -D_GLFW_X11 \
 -I \
 ../../../glfw/v3.2/glfw/glfw/include/GLFW/ \
 main.c \
 ../../../glfw/v3.2/glfw/glfw/src/context.c \
 ../../../glfw/v3.2/glfw/glfw/src/init.c \
 ../../../glfw/v3.2/glfw/glfw/src/input.c \
 ../../../glfw/v3.2/glfw/glfw/src/monitor.c \
 ../../../glfw/v3.2/glfw/glfw/src/vulkan.c \
 ../../../glfw/v3.2/glfw/glfw/src/window.c \
 ../../../glfw/v3.2/glfw/glfw/src/x11_init.c \
 ../../../glfw/v3.2/glfw/glfw/src/x11_monitor.c \
 ../../../glfw/v3.2/glfw/glfw/src/x11_window.c \
 ../../../glfw/v3.2/glfw/glfw/src/glx_context.c \
 ../../../glfw/v3.2/glfw/glfw/src/linux_joystick.c \
 ../../../glfw/v3.2/glfw/glfw/src/posix_time.c \
 ../../../glfw/v3.2/glfw/glfw/src/posix_tls.c \
 ../../../glfw/v3.2/glfw/glfw/src/xkb_unicode.c \
 ../../../glfw/v3.2/glfw/glfw/src/egl_context.c \
 -lGL \
 -lX11 \
 -lXrandr \
 -lXxf86vm \
 -lXi \
 -lXcursor \
 -lm \
 -lXinerama \
 -ldl \
 -lrt \
 -pthread

With a main.c:

#include <glfw3.h>
#include <stdio.h>

int main(int argc, char const *argv[]) {
  glfwInit();
  return 0;
}

So, the long and short of it is, I'm not sure what is triggering this.

My first attempt at using gdb didn't get anywhere and just resulted in segfaults. But for some reason it's working now. I was able to hit it while single stepping.

Thread 1 "gl41core-cube" hit Breakpoint 1, glfwInit () at /home/pwaller/.local/src/github.com/go-gl/glfw/v3.2/glfw/glfw/src/init.c:122
122	    if (_glfwInitialized)
(gdb) step
125	    memset(&_glfw, 0, sizeof(_glfw));
(gdb) 
127	    if (!_glfwPlatformInit())
(gdb) 
_glfwPlatformInit () at /home/pwaller/.local/src/github.com/go-gl/glfw/v3.2/glfw/glfw/src/x11_init.c:748
748	    _glfw.x11.cursor = createHiddenCursor();
(gdb) 
createHiddenCursor () at /home/pwaller/.local/src/github.com/go-gl/glfw/v3.2/glfw/glfw/src/x11_init.c:625
625	    unsigned char pixels[16 * 16 * 4];
(gdb) 
_glfwPlatformInit () at /home/pwaller/.local/src/github.com/go-gl/glfw/v3.2/glfw/glfw/src/x11_init.c:745
745	    if (!initExtensions())
(gdb) 
initExtensions () at /home/pwaller/.local/src/github.com/go-gl/glfw/v3.2/glfw/glfw/src/x11_init.c:745
745	    if (!initExtensions())
(gdb) 
createKeyTables () at /home/pwaller/.local/src/github.com/go-gl/glfw/v3.2/glfw/glfw/src/x11_init.c:243
243	        char name[XkbKeyNameLength + 1];
(gdb) 
_glfwPlatformInit () at /home/pwaller/.local/src/github.com/go-gl/glfw/v3.2/glfw/glfw/src/x11_init.c:721
721	    XInitThreads();
(gdb) 
723	    _glfw.x11.display = XOpenDisplay(NULL);
(gdb) 
724	    if (!_glfw.x11.display)
(gdb) 
741	    _glfw.x11.screen = DefaultScreen(_glfw.x11.display);
(gdb) 
742	    _glfw.x11.root = RootWindow(_glfw.x11.display, _glfw.x11.screen);
(gdb) 
741	    _glfw.x11.screen = DefaultScreen(_glfw.x11.display);
(gdb) 
742	    _glfw.x11.root = RootWindow(_glfw.x11.display, _glfw.x11.screen);
(gdb) 
741	    _glfw.x11.screen = DefaultScreen(_glfw.x11.display);
(gdb) 
742	    _glfw.x11.root = RootWindow(_glfw.x11.display, _glfw.x11.screen);
(gdb) 
743	    _glfw.x11.context = XUniqueContext();
(gdb)
745	    if (!initExtensions())
(gdb) 
initExtensions () at /home/pwaller/.local/src/github.com/go-gl/glfw/v3.2/glfw/glfw/src/x11_init.c:474
474	    if (XRRQueryExtension(_glfw.x11.display,
(gdb)
478	        if (XRRQueryVersion(_glfw.x11.display,
(gdb)
483	            if (_glfw.x11.randr.major > 1 || _glfw.x11.randr.minor >= 3)
(gdb) 
484	                _glfw.x11.randr.available = GLFW_TRUE;
(gdb) 
496	                                                       _glfw.x11.root);
(gdb) 
495	        XRRScreenResources* sr = XRRGetScreenResources(_glfw.x11.display,
(gdb) 
496	                                                       _glfw.x11.root);
(gdb) 
495	        XRRScreenResources* sr = XRRGetScreenResources(_glfw.x11.display,
(gdb)
498	        if (!sr->ncrtc || !XRRGetCrtcGammaSize(_glfw.x11.display, sr->crtcs[0]))
(gdb) 
==1344==WARNING: MemorySanitizer: use-of-uninitialized-value
    #0 0x6ff345  (/home/pwaller/.local/src/github.com/go-gl/examples/gl41core-cube/gl41core-cube+0x6ff345)
    #1 0x6ed1dd  (/home/pwaller/.local/src/github.com/go-gl/examples/gl41core-cube/gl41core-cube+0x6ed1dd)
    #2 0x71b91f  (/home/pwaller/.local/src/github.com/go-gl/examples/gl41core-cube/gl41core-cube+0x71b91f)
    #3 0x4f06cf  (/home/pwaller/.local/src/github.com/go-gl/examples/gl41core-cube/gl41core-cube+0x4f06cf)

SUMMARY: MemorySanitizer: use-of-uninitialized-value (/home/pwaller/.local/src/github.com/go-gl/examples/gl41core-cube/gl41core-cube+0x6ff345) 
Exiting
[Thread 0x7ffff2e02700 (LWP 1347) exited]
[Thread 0x7ffff3907700 (LWP 1346) exited]
[Thread 0x7ffff440c700 (LWP 1345) exited]
[Thread 0x7ffff7fc0440 (LWP 1344) exited]
warning: Error removing breakpoint 0
warning: Error removing breakpoint 0
warning: Error removing breakpoint 0
warning: Error removing breakpoint 0
warning: Error removing breakpoint 0

So it looks like the problematic line is line 498 of x11_init.c.

if (!sr->ncrtc || !XRRGetCrtcGammaSize(_glfw.x11.display, sr->crtcs[0]))

Ah wait, msan != -fsanitize=address.

If I use -fsanitize=memory, then the c program fails too:

Uninitialized bytes in read_iovec at offset 0 inside [0x70400000ec60, 18)
==1969==WARNING: MemorySanitizer: use-of-uninitialized-value
    #0 0x429e88  (/home/pwaller/.local/src/github.com/go-gl/examples/gl41core-cube/init/a.out+0x429e88)
    #1 0x7f997d193f28  (/usr/lib/x86_64-linux-gnu/libxcb.so.1+0x9f28)
    #2 0x7f997d19431c  (/usr/lib/x86_64-linux-gnu/libxcb.so.1+0xa31c)
    #3 0x7f997d193a57  (/usr/lib/x86_64-linux-gnu/libxcb.so.1+0x9a57)
    #4 0x7f997d197610  (/usr/lib/x86_64-linux-gnu/libxcb.so.1+0xd610)
    #5 0x7f997f241809  (/usr/lib/x86_64-linux-gnu/libX11.so.6+0x3c809)
    #6 0x7f997f232391  (/usr/lib/x86_64-linux-gnu/libX11.so.6+0x2d391)
    #7 0x4b4172  (/home/pwaller/.local/src/github.com/go-gl/examples/gl41core-cube/init/a.out+0x4b4172)
    #8 0x4936ba  (/home/pwaller/.local/src/github.com/go-gl/examples/gl41core-cube/init/a.out+0x4936ba)
    #9 0x48928c  (/home/pwaller/.local/src/github.com/go-gl/examples/gl41core-cube/init/a.out+0x48928c)
    #10 0x7f997d8e682f  (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
    #11 0x41bd88  (/home/pwaller/.local/src/github.com/go-gl/examples/gl41core-cube/init/a.out+0x41bd88)

SUMMARY: MemorySanitizer: use-of-uninitialized-value (/home/pwaller/.local/src/github.com/go-gl/examples/gl41core-cube/init/a.out+0x429e88) 

It might not be the same failure. But until someone can demonstrate that this is the go library's fault, I think we must conclude it is not for now. If this is a problem for you, please follow it up upstream. Given that the C program which just calls glfwInit fails, it seems unlikely that there is a quick fix on our side.

Thanks for reporting, but I will close this for now unless anyone follows up with further evidence and an actionable bug report.