[Mesa-dev] [RFC PATCH 1/1] i965: avoid possible 'SIGFPE, Arithmetic exception.' during error path.

Oliver McFadden oliver.mcfadden at linux.intel.com
Mon May 14 08:43:47 PDT 2012


Mesa: User error: GL_INVALID_OPERATION in glUniformMatrix(non-matrix uniform)

Program received signal SIGFPE, Arithmetic exception.
0x................ in brw_prepare_vertices (brw=0x.......) at brw_draw_upload.c:571
571                 delta = d / brw->vb.current_buffers[i].stride;

Occurs when glEnableVertexAttribArray() is called with an invalid index
(triggering the first MESA_DEBUG warning) followed by calling
glDrawElements() eventually triggering the divide-by-zero.

This particular case was triggered by forgetting to call
glGetAttribLocation() for all attributes used by the shader, therefore
at least one attribute was left initialized to zero.

It should be impossible for the OpenGL client to crash the driver by submitting
invalid data, therefore for the sake of robustness skip over this vertex buffer
if the stride would cause a divide-by-zero arithmetic exception.

Signed-off-by: Oliver McFadden <oliver.mcfadden at linux.intel.com>
---

RFC: I am unsure whether this is the correct solution or whether the
verification should be done in the higher level code?

I think it's kind of nasty to do this on the driver level, right when we're
about to emit the vertices.  I'm not even sure this is the correct solution
(however it avoids the crash and I didn't notice any errors other than the
offending shader not rendering, as expected.)

I am also unsure what would happen were the same code executed on a different
GPU.  Unfortunately I do not have a large selection of hardware nor a small test
case to provide (though it shouldn't be too much trouble to write one... famous
last words, eh?)

 src/mesa/drivers/dri/i965/brw_draw_upload.c |   10 +++++++---
 1 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_draw_upload.c b/src/mesa/drivers/dri/i965/brw_draw_upload.c
index 11b9caa..5421a9d 100644
--- a/src/mesa/drivers/dri/i965/brw_draw_upload.c
+++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c
@@ -558,18 +558,22 @@ static void brw_prepare_vertices(struct brw_context *brw)
    if (j == brw->vb.nr_current_buffers) {
       int delta = 0;
       for (i = 0; i < j; i++) {
-	 int d;
+	 int d, s;
 
 	 if (brw->vb.current_buffers[i].handle != brw->vb.buffers[i].bo->handle ||
 	     brw->vb.current_buffers[i].stride != brw->vb.buffers[i].stride)
 	    break;
 
 	 d = brw->vb.buffers[i].offset - brw->vb.current_buffers[i].offset;
+	 s = brw->vb.current_buffers[i].stride;
+
 	 if (d < 0)
 	    break;
+	 if (s <= 0)	/* Arithmetic exception */
+	   continue;
 	 if (i == 0)
-	    delta = d / brw->vb.current_buffers[i].stride;
-	 if (delta * brw->vb.current_buffers[i].stride != d)
+	    delta = d / s;
+	 if (delta * s != d)
 	    break;
       }
 
-- 
1.7.8



More information about the mesa-dev mailing list