From d9ef54923804d5fe44a1d3ad5c29e9b8e8382359 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Fri, 20 Jan 2017 02:26:42 +0100 Subject: [PATCH] st/mesa: destroy pipe_context before destroying st_context (v2) MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit If radeonsi starts compiling an optimized shader variant asynchronously with a GL debug callback set and the application destroys the GL context, radeonsi crashes when trying to write shader stats into the debug output of a non-existent context after compilation, because st/mesa was destroyed before pipe_context. Firefox with WebGL2 enabled hits this bug. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=99456 v2: protect against a double destroy in st_create_context_priv and callers. Cc: 17.0 Reviewed-by: Nicolai Hähnle --- src/mesa/state_tracker/st_context.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c index 0eae971143b..55237345fc1 100644 --- a/src/mesa/state_tracker/st_context.c +++ b/src/mesa/state_tracker/st_context.c @@ -278,7 +278,7 @@ void st_invalidate_state(struct gl_context * ctx, GLbitfield new_state) static void -st_destroy_context_priv(struct st_context *st) +st_destroy_context_priv(struct st_context *st, bool destroy_pipe) { uint shader, i; @@ -314,6 +314,10 @@ st_destroy_context_priv(struct st_context *st) st_invalidate_readpix_cache(st); cso_destroy_context(st->cso_context); + + if (st->pipe && destroy_pipe) + st->pipe->destroy(st->pipe); + free( st ); } @@ -503,7 +507,7 @@ st_create_context_priv( struct gl_context *ctx, struct pipe_context *pipe, /* This can happen when a core profile was requested, but the driver * does not support some features of GL 3.1 or later. */ - st_destroy_context_priv(st); + st_destroy_context_priv(st, false); return NULL; } @@ -579,7 +583,6 @@ destroy_tex_sampler_cb(GLuint id, void *data, void *userData) void st_destroy_context( struct st_context *st ) { - struct pipe_context *pipe = st->pipe; struct gl_context *ctx = st->ctx; GLuint i; @@ -608,11 +611,9 @@ void st_destroy_context( struct st_context *st ) /* This will free the st_context too, so 'st' must not be accessed * afterwards. */ - st_destroy_context_priv(st); + st_destroy_context_priv(st, true); st = NULL; - pipe->destroy( pipe ); - free(ctx); } -- 2.30.2