Segmentation fault under Agg

I've encountered a segmentation fault using the Agg backend when making and saving a png plot. The segmentation fault does not seem to occur under different backends (e.g. Cairo).

The sequence of commands amounts to making a plot, setting the limits of the plot, then saving the plot as a png using savefig. If the value of one of the points is too large, a segmentation fault is generated. Obviously the simple work-around is to not plot the out-of-bounds points, but the segmentation fault is probably not the desired behavior!

Below is an example, which generates a segmentation fault on matplotlib versions 0.99.0 (run on OS X 10.5.8) and 0.98.5.2 (run on Fedora 11 and CentOS 5.3).

Can others reproduce this issue?

Thanks,
Mike Nicolls

import scipy
import matplotlib
matplotlib.use('Agg')
import pylab

if __name__ == '__main__':
        xdata,ydata = scipy.rand(2,10)
    xdata[3]=1.0e9 # comment out to avoid seg fault
        pylab.figure()
    pylab.plot(xdata,ydata,'k.')
    pylab.xlim((0.0,1.0))
        pylab.savefig('test.png')

Thanks for the report -- I can confirm this on OSX and linux on svn HEAD

I've made minor tweaks to your test case to make it deterministic::

    import numpy as np
    import matplotlib
    matplotlib.use('Agg')
    import matplotlib.pyplot as plt

    xdata = np.arange(10.0)
    ydata = np.arange(10.0)

    xdata[3]=1.0e9 # comment out to avoid seg fault

    fig = plt.figure()
    ax = fig.add_subplot(111)
    ax.plot(xdata,ydata,'k.')
    ax.set_xlim(0.0,1.0)

    fig.savefig('test.png')

and added a bug report to :

  https://sourceforge.net/tracker/?func=detail&aid=2865490&group_id=80706&atid=560720

Platforms confirmed w/ bug:

home:~> uname -a
Darwin Macintosh-8.local 9.8.0 Darwin Kernel Version 9.8.0: Wed Jul 15
16:55:01 PDT 2009; root:xnu-1228.15.4~1/RELEASE_I386 i386

jdhunter@...2795...:~> uname -a
Linux uqbar 2.6.27-14-generic #1 SMP Tue Jun 30 19:54:46 UTC 2009
x86_64 GNU/Linux

···

On Wed, Sep 23, 2009 at 6:47 PM, Mike Nicolls <michael.nicolls@...392...> wrote:

I've encountered a segmentation fault using the Agg backend when making
and saving a png plot. The segmentation fault does not seem to occur
under different backends (e.g. Cairo).

The sequence of commands amounts to making a plot, setting the limits of
the plot, then saving the plot as a png using savefig. If the value of
one of the points is too large, a segmentation fault is generated.
Obviously the simple work-around is to not plot the out-of-bounds
points, but the segmentation fault is probably not the desired behavior!

Below is an example, which generates a segmentation fault on matplotlib
versions 0.99.0 (run on OS X 10.5.8) and 0.98.5.2 (run on Fedora 11 and
CentOS 5.3).

Can others reproduce this issue?

I applied the following patch to the branch and head -- it feels like there
would be a more elegant way to handle it, so I'd like Michael at least to
take a look at it::

home:~/mpl> svn diff -rPREV:HEAD src/_backend_agg.cpp
Index: src/_backend_agg.cpp

···

On Wed, Sep 23, 2009 at 10:15 PM, John Hunter <jdh2358@...287...> wrote:

On Wed, Sep 23, 2009 at 6:47 PM, Mike Nicolls <michael.nicolls@...392...> wrote:

I've encountered a segmentation fault using the Agg backend when making
and saving a png plot. The segmentation fault does not seem to occur
under different backends (e.g. Cairo).

The sequence of commands amounts to making a plot, setting the limits of
the plot, then saving the plot as a png using savefig. If the value of
one of the points is too large, a segmentation fault is generated.
Obviously the simple work-around is to not plot the out-of-bounds
points, but the segmentation fault is probably not the desired behavior!

Below is an example, which generates a segmentation fault on matplotlib
versions 0.99.0 (run on OS X 10.5.8) and 0.98.5.2 (run on Fedora 11 and
CentOS 5.3).

Can others reproduce this issue?

Thanks for the report -- I can confirm this on OSX and linux on svn HEAD

I've made minor tweaks to your test case to make it deterministic::

===================================================================
--- src/_backend_agg.cpp (revision 7820)
+++ src/_backend_agg.cpp (revision 7821)
@@ -608,6 +608,14 @@

x = (double)(int)x; y = (double)(int)y;

+ // if x or y is close to the width or height, the filled
+ // region could be inside the boundary even if the center is
+ // out. But at some point we need to cull these points
+ // because they can create segfaults of they overflow; eg
+ //
https://sourceforge.net/tracker/?func=detail&aid=2865490&group_id=80706&atid=560720
+ if (fabs(x)>(2*width)) continue;
+ if (fabs(y)>(2*height)) continue;
+
pixfmt_amask_type pfa(pixFmt, alphaMask);
amask_ren_type r(pfa);
amask_aa_renderer_type ren(r);
@@ -629,6 +637,14 @@

x = (double)(int)x; y = (double)(int)y;

+ // if x or y is close to the width or height, the filled
+ // region could be inside the boundary even if the center is
+ // out. But at some point we need to cull these points
+ // because they can create segfaults of they overflow; eg
+ //
https://sourceforge.net/tracker/?func=detail&aid=2865490&group_id=80706&atid=560720
+ if (fabs(x)>(2*width)) continue;
+ if (fabs(y)>(2*height)) continue;
+
if (face.first) {
rendererAA.color(face.second);
sa.init(fillCache, fillSize, x, y);

I committed a slightly tighter version of this that uses a rectangle based on the size of the image plus a border to accomodate the exact marker size. Probably makes very little difference, but I suppose if there was a dense field of markers outside of view, this might speed things up a bit more.

A further optimization might be to use the clipping rectangle, but that's not necessary merely to prevent the segfault.

Mike

···

On 09/24/2009 12:06 AM, John Hunter wrote:

On Wed, Sep 23, 2009 at 10:15 PM, John Hunter<jdh2358@...287...> wrote:
   

On Wed, Sep 23, 2009 at 6:47 PM, Mike Nicolls<michael.nicolls@...392...> wrote:
     

I've encountered a segmentation fault using the Agg backend when making
and saving a png plot. The segmentation fault does not seem to occur
under different backends (e.g. Cairo).

The sequence of commands amounts to making a plot, setting the limits of
the plot, then saving the plot as a png using savefig. If the value of
one of the points is too large, a segmentation fault is generated.
Obviously the simple work-around is to not plot the out-of-bounds
points, but the segmentation fault is probably not the desired behavior!

Below is an example, which generates a segmentation fault on matplotlib
versions 0.99.0 (run on OS X 10.5.8) and 0.98.5.2 (run on Fedora 11 and
CentOS 5.3).

Can others reproduce this issue?
       

Thanks for the report -- I can confirm this on OSX and linux on svn HEAD

I've made minor tweaks to your test case to make it deterministic::
     

I applied the following patch to the branch and head -- it feels like there
would be a more elegant way to handle it, so I'd like Michael at least to
take a look at it::

home:~/mpl> svn diff -rPREV:HEAD src/_backend_agg.cpp
Index: src/_backend_agg.cpp

--- src/_backend_agg.cpp (revision 7820)
+++ src/_backend_agg.cpp (revision 7821)
@@ -608,6 +608,14 @@

x = (double)(int)x; y = (double)(int)y;

+ // if x or y is close to the width or height, the filled
+ // region could be inside the boundary even if the center is
+ // out. But at some point we need to cull these points
+ // because they can create segfaults of they overflow; eg
+ //
https://sourceforge.net/tracker/?func=detail&aid=2865490&group_id=80706&atid=560720
+ if (fabs(x)>(2*width)) continue;
+ if (fabs(y)>(2*height)) continue;
+
pixfmt_amask_type pfa(pixFmt, alphaMask);
amask_ren_type r(pfa);
amask_aa_renderer_type ren(r);
@@ -629,6 +637,14 @@

x = (double)(int)x; y = (double)(int)y;

+ // if x or y is close to the width or height, the filled
+ // region could be inside the boundary even if the center is
+ // out. But at some point we need to cull these points
+ // because they can create segfaults of they overflow; eg
+ //
https://sourceforge.net/tracker/?func=detail&aid=2865490&group_id=80706&atid=560720
+ if (fabs(x)>(2*width)) continue;
+ if (fabs(y)>(2*height)) continue;
+
if (face.first) {
rendererAA.color(face.second);
sa.init(fillCache, fillSize, x, y);

------------------------------------------------------------------------------
Come build with us! The BlackBerry&reg; Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay
ahead of the curve. Join us from November 9&#45;12, 2009. Register now&#33;
http://p.sf.net/sfu/devconf
_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-users