go-gl / example

Example programs for the various go-gl packages.
MIT License
223 stars 59 forks source link

Go 1.6 -msan option error (memory sanitizer) #53

Closed zzz125 closed 7 years ago

zzz125 commented 8 years ago

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.

dmitshur commented 8 years ago

use-of-uninitialized-value

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

zzz125 commented 8 years ago

@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.

dmitshur commented 8 years ago

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.

pwaller commented 7 years ago

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.

pwaller commented 7 years ago

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]))
pwaller commented 7 years ago

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.