baldurk / renderdoc

RenderDoc is a stand-alone graphics debugging tool.
https://renderdoc.org
MIT License
8.94k stars 1.34k forks source link

Segmentation fault on Windows in wglCreateContext(hdc) #2669

Closed szabolcsdombi closed 2 years ago

szabolcsdombi commented 2 years ago

Description

with pyglet:

Traceback (most recent call last):
  File "D:\Programming\zengl\examples\crate.py", line 11, in <module>
    window = Window()
  File "D:\Programming\zengl\examples\window.py", line 122, in __init__
    self._wnd = PygletWindow(*size)
  File "D:\Programming\zengl\examples\window.py", line 80, in __init__
    super().__init__(width=width, height=height, config=config, vsync=True)
  File "C:\Users\Szabi\AppData\Local\Programs\Python\Python310\lib\site-packages\pyglet\window\win32\__init__.py", line 136, in __init__
    super(Win32Window, self).__init__(*args, **kwargs)
  File "C:\Users\Szabi\AppData\Local\Programs\Python\Python310\lib\site-packages\pyglet\window\__init__.py", line 658, in __init__
    self._create()
  File "C:\Users\Szabi\AppData\Local\Programs\Python\Python310\lib\site-packages\pyglet\window\win32\__init__.py", line 297, in _create
    self.context.attach(self.canvas)
  File "C:\Users\Szabi\AppData\Local\Programs\Python\Python310\lib\site-packages\pyglet\gl\win32.py", line 231, in attach
    self._context = wgl.wglCreateContext(canvas.hdc)
OSError: exception: access violation reading 0x0000000000000020

with pygame:

pygame 2.1.0 (SDL 2.0.16, Python 3.10.4)
Hello from the pygame community. https://www.pygame.org/contribute.html
Fatal Python error: pygame_parachute: (pygame parachute) Segmentation Fault
Python runtime state: initialized

Current thread 0x00001ffc (most recent call first):
  File "D:\Programming\zengl\examples\example_project\window.py", line 13 in __init__
  File "D:\Programming\zengl\examples\example_project\main.py", line 9 in <module>

Extension modules: numpy.core._multiarray_umath, numpy.core._multiarray_tests, numpy.linalg._umath_linalg, numpy.fft._pocketfft_internal, numpy.random._common, numpy.random.bit_generator, numpy.random._bounded_integers, numpy.random._mt19937, numpy.random.mtrand, numpy.random._philox, numpy.random._pcg64, numpy.random._sfc64, numpy.random._generator, zengl, pygame.base, pygame.constants, pygame.rect, pygame.rwobject, pygame.surflock, pygame.color, pygame.bufferproxy, pygame.math, pygame.surface, pygame.display, pygame.draw, pygame.event, pygame.imageext, pygame.image, pygame.joystick, pygame.key, pygame.mouse, pygame.time, pygame.mask, pygame.pixelcopy, pygame.transform, pygame.font, pygame.mixer_music, pygame.mixer, pygame.scrap, pygame.fastevent, pygame._freetype (total: 41)

Rolling back to v1.20 resolves the problem for the pygame window. (this example used to work in the past) The pyglet window gets stuck in a DwmFlush(). (this example was not tested in the past)

Steps to reproduce

Set this to get a core profile:

        pg.init()
        pg.display.gl_set_attribute(pg.GL_CONTEXT_MAJOR_VERSION, 3)
        pg.display.gl_set_attribute(pg.GL_CONTEXT_MINOR_VERSION, 3)
        pg.display.gl_set_attribute(pg.GL_CONTEXT_PROFILE_MASK, pg.GL_CONTEXT_PROFILE_CORE)
        pg.display.set_mode((width, height), pg.OPENGL | pg.DOUBLEBUF)

Environment

I first reported this issue at https://github.com/pyglet/pyglet/issues/661. A few days ago the pygame example worked well and made me think the pyglet window breaks because of RenderDoc. Actually it does as it says white compared to pygame window, but now I assume it may also be caused by RenderDoc.

baldurk commented 2 years ago

I'm not able to reproduce this. I installed pygame and downloaded the source repo (from https://github.com/pygame/pygame) to get an example, using the aliens example from the documentation I modified it as you specified, with hardcoded width/height since they weren't defined variables:

def main(winstyle=0):
    # Initialize pygame
    if pg.get_sdl_version()[0] == 2:
        pg.mixer.pre_init(44100, 32, 2, 1024)
    pg.init()
    pg.display.gl_set_attribute(pg.GL_CONTEXT_MAJOR_VERSION, 3)
    pg.display.gl_set_attribute(pg.GL_CONTEXT_MINOR_VERSION, 3)
    pg.display.gl_set_attribute(pg.GL_CONTEXT_PROFILE_MASK, pg.GL_CONTEXT_PROFILE_CORE)
    pg.display.set_mode((500, 500), pg.OPENGL | pg.DOUBLEBUF)
    if pg.mixer and not pg.mixer.get_init():
        print("Warning, no sound")
        pg.mixer = None

But when running it from RenderDoc I see an OpenGL context initialised and briefly used on a black screen then the rest of the rendering seems to not use OpenGL. Apart from a handful of context creation calls and a few swaps it doesn't seem to be using OpenGL at all, and doesn't crash.

If this is expected then I'm not able to reproduce the issue, if it's not then I'm not sure I'm following the right steps. Please provide a more complete reproducible test case that I can follow that doesn't assume familiarity with whichever library or code you are using, as I don't know anything about pygame.

szabolcsdombi commented 2 years ago

Hi. Thank you for the quick reply. I made a video and pasted all the code below.

https://user-images.githubusercontent.com/11232402/182144487-c1afd792-8abb-441a-8e7d-3d6efbbfcf76.mp4

import time

import pygame as pg

class Window:
    def __init__(self, width, height):
        self.time = 0.0
        self.alive = True
        self.frames = 0

        pg.init()
        pg.display.gl_set_attribute(pg.GL_CONTEXT_MAJOR_VERSION, 3)
        pg.display.gl_set_attribute(pg.GL_CONTEXT_MINOR_VERSION, 3)
        pg.display.gl_set_attribute(pg.GL_CONTEXT_PROFILE_MASK, pg.GL_CONTEXT_PROFILE_CORE)
        pg.display.set_mode((width, height), pg.OPENGL | pg.DOUBLEBUF)
        width, height = pg.display.get_surface().get_size()
        self.size = width, height
        self.aspect = width / height

    def update(self):
        self.frames += 1
        pg.display.flip()
        pg.time.wait(10)
        self.time += 1.0 / 60.0
        for event in pg.event.get():
            if event.type == pg.QUIT:
                self.alive = False
        return self.alive

print('creating a window')
time.sleep(1.0)

window = Window(640, 480)

print('window created')
time.sleep(1.0)

while window.update():
    if window.frames % 100 == 0:
        print('+100 frames')

print('window closed')
time.sleep(1.0)
Fatal Python error: pygame_parachute: (pygame parachute) Segmentation Fault
Python runtime state: initialized

Current thread 0x000053bc (most recent call first):
  File "D:\Programming\zengl\test.py", line 16 in __init__
  File "D:\Programming\zengl\test.py", line 35 in <module>

Extension modules: pygame.base, pygame.constants, pygame.rect, pygame.rwobject, pygame.surflock, pygame.color, pygame.bufferproxy, pygame.math, pygame.surface, pygame.display, pygame.draw, pygame.event, pygame.imageext, pygame.image, pygame.joystick, pygame.key, pygame.mouse, pygame.time, pygame.mask, pygame.pixelcopy, pygame.transform, pygame.font, pygame.mixer_music, pygame.mixer, pygame.scrap, numpy.core._multiarray_umath, numpy.core._multiarray_tests, numpy.linalg._umath_linalg, numpy.fft._pocketfft_internal, numpy.random._common, numpy.random.bit_generator, numpy.random._bounded_integers, numpy.random._mt19937, numpy.random.mtrand, numpy.random._philox, numpy.random._pcg64, numpy.random._sfc64, numpy.random._generator, pygame.fastevent, pygame._freetype (total: 40)
baldurk commented 2 years ago

Thanks, I'm able to run that program now but I can't reproduce the bug unfortunately - for me it runs and captures correctly on v1.21. I've tried on a couple of different GPUs with the same result. The only thing I'm unable to replicate is running on windows 11. Are you able to test on any other PCs to see if it's more widely reproducible?

Also in your video one thing that seems strange is there's no administrator prompt to update, and RenderDoc didn't re-open after the update. Is that something you removed from the video or is that how it actually happens for you? Does this problem still happen if you download the v1.21 zip from the website and run it directly?

If you're not able to test on another machine and it still reproduces with the zip download, would you be able to use nightly builds between 1ed4b561, 2021-05-27 (v1.20) and 98a93408, 2022-07-27 (v1.21) to narrow down when the problem started happening?

szabolcsdombi commented 2 years ago

there's no administrator prompt to update,

there was, but it is not possible to record it with a non administrator process (ScreenToGif).

RenderDoc didn't re-open after the update

It did, after the video I found it started minimized as I had to close 2 RenderDoc UIs. I re-recorded the video not to make this mistake, but I did it anyways.

I can only run Win11 on this machine, I have a few running Win10 I test on those too.

Actually I often reinstall my system to avoid bugs comming from updates and dangling state. My system is quite recent (‎Saturday, ‎5 ‎June, ‎2021, ‏‎3:01:25 PM).

I will test the nightly builds and I also try to get a memory dump or at least some traces.

baldurk commented 2 years ago

Can you also please re-test with the latest nightly build? I made a fix that might be related to this, though I don't think it would explain a crash unless there's a driver issue.

szabolcsdombi commented 2 years ago

Okay, i test it

szabolcsdombi commented 2 years ago

Success! :) it works Can you tell me more about the driver bug that should cause it?

szabolcsdombi commented 2 years ago

image

baldurk commented 2 years ago

I'm just guessing. I had a bug that would use incorrect context properties to create shared contexts for fetching resources. It wouldn't crash in RenderDoc's code that I'm aware of so it presumably was crashing in the driver. Technically in OpenGL the driver should never crash, and always just return an error code, but in practice that's not always feasible.

szabolcsdombi commented 2 years ago

RenderDoc_2022_07_27_98a93408_64 crashes RenderDoc_2022_07_31_44a1de01_64 crashes RenderDoc_2022_08_02_423da6b3_64 works