[Mono-dev] SIGSEGV in Cairo.CairoAPI:cairo_get/set_matrix()
John Luke
john.luke at gmail.com
Mon Oct 31 16:26:56 EST 2005
Hey,
I think ref is used in too many places. Perhaps I am wrong, but at
least for the set_* methods they won't be modifying it.
Maybe going through the cairo docs can help you decide to use
out/ref/neither for each of those calls, if you didn't already.
For example, cairo_get_matrix looks like it should be out, and
cairo_set_matrix looks like it should not be ref or out.
For the Matrix struct, the public fields should have the first letter
capitalized.
The rest looks sane, but I haven't tested it. Do any of the samples use
these parts? and if so do they work with these changes?
Hope that helps.
Idan Gazit wrote:
> Ok, so attached is a patch covering the items I mention below.
>
> I expect somebody more experienced with Mono.Cairo should look this
> over, I expect I'll have to make some changes. *nudging Hisham/JLuke*...
>
> Regarding the broken ref arguments, I filed:
>
> http://bugzilla.ximian.com/show_bug.cgi?id=76603
>
> in this regards.
>
> Should I break this patch up into two pieces, one to fix the ref issue
> and one for everything else?
>
> -Idan
>
>
> Idan Gazit wrote:
>
>> OK, So this email touches on Mono.Cairo in 3 parts:
>>
>> 1. SIGSEGV
>> ==========
>>
>> OK, I got some help from Michael Dominic, who pointed out that
>>
>> cairo_get_matrix (IntPtr cr, Matrix_T matrix);
>>
>> should really be:
>>
>> cairo_get_matrix (IntPtr cr, ref Matrix_T matrix);
>>
>> It seems that any CairoAPI function which takes a matrix should pass a
>> ref Matrix_T and not a Matrix_T. This seems to include the following:
>>
>> cairo_transform
>> cairo_get/set_matrix
>> cairo_set_font_matrix
>> cairo_pattern_get/set_matrix
>>
>> I'm preparing a patch to this effect.
>>
>>
>> 2. Class Or Struct?
>> ===================
>>
>> About this time, lewing (in #mono) suggested that there's no point for
>> Matrix to be a class hiding a Matrix_T struct, rather make Matrix a
>> struct. So I went ahead and did this, and I'm testing it now (looks OK).
>>
>> I don't know the reasons behind wrapping Matrix_T in a class, so can
>> somebody tell me (not sarcastic) why? If there are advantages to having
>> Matrix be a struct and doing away with Matrix_T then I have the patch
>> ready to go.
>>
>> 3. Miscellaneous Design Improvements(?)
>> =======================================
>>
>> Either way to go (struct or class), I saw a few places where changes
>> seemed logical to me:
>>
>> - "Identify" should be "Identity"
>> - Have Translate/Rotate/Scale et al return (this); so as to enable
>> things like myMatrix.Translate().Rotate().Scale().
>> - public static Matrix Identity property as an easy way of getting at
>> the identity matrix.
>> - No need for Pointer nor Raw properties in Matrix (they're not used
>> elsewhere...)?
>> - override Matrix.ToString () to produce something useful for debugging.
>>
>>
>> At any rate, all of these together constitutes a patch to Cairo.cs,
>> Graphics.cs, Matrix.cs, and Pattern.cs. I can make patches for each of
>> the three individually, or whatever.
>>
>> Please let me know how to proceed, I'd be very happy to put in my first
>> patch for mono. :)
>>
>> -Idan
>>
>>
>> Idan Gazit wrote:
>>
>>
>>> Hey,
>>>
>>> So I manage to segfault when playing with the Graphics.Matrix
>>> property. Basically anything that would result in a call to
>>> cairo_get_matrix or cairo_set_matrix segfaults.
>>>
>>> The stacktrace for this segfault when doing get is below, but
>>> triggering it is pretty easy:
>>>
>>> // set up graphics here, then
>>> System.Console.WriteLine(g.Matrix.ToString());
>>>
>>> the same for set:
>>>
>>> Cairo.Matrix transformMatrix = new Cairo.Matrix ();
>>> transformMatrix.CreateIdentify ();
>>> // set up graphics here, then
>>> g.Matrix = transformMatrix;
>>>
>>>
>>> Should I be talking to the cairo devs aobut this, instead?
>>>
>>> -Idan
>>>
>>> =================================================================
>>> Got a SIGSEGV while executing native code. This usually indicates
>>> a fatal error in the mono runtime or one of the native libraries
>>> used by your application.
>>> =================================================================
>>>
>>> Stacktrace:
>>>
>>>
>>> Native stacktrace:
>>>
>>> in <0x4> (wrapper managed-to-native) Cairo.CairoAPI:cairo_get_matrix
>>> (intptr,Cairo.Matrix_T)
>>> in <0xffffffa1> (wrapper managed-to-native)
>>> Cairo.CairoAPI:cairo_get_matrix (intptr,Cairo.Matrix_T)
>>> in <0x49> Cairo.Graphics:get_Matrix ()
>>> in [0xc1] Meshwork.NetworkMap.ZoomableCairoArea:OnExposeEvent
>>> (Gdk.EventExpose)
>>> in [0x14] Gtk.Widget:exposeevent_cb (intptr,intptr)
>>> in <0x49cce3> (wrapper native-to-managed) Gtk.Widget:exposeevent_cb
>>> (intptr,intptr)
>>> in <0x4> (wrapper managed-to-native) Gtk.Application:gtk_main ()
>>> in <0xffffffe7> (wrapper managed-to-native) Gtk.Application:gtk_main ()
>>> in [0x0] Gtk.Application:Run ()
>>> in [0xb] MainClass:Main (string[])
>>> in <0x50bbe2f9> (wrapper runtime-invoke)
>>> System.Object:runtime_invoke_void_string[] (object,intptr,intptr,intptr)
>>> mono(mono_handle_native_sigsegv+0x73) [0x813d883]
>>> mono [0x81108db]
>>> [0xffffe440]
>>> /usr/lib/libcairo.so.2(cairo_get_matrix+0x1b) [0xb69343fb]
>>> [0xb67d4064]
>>> [0xb67d3fc2]
>>> [0xb67d0145]
>>> [0xb67cf725]
>>> [0xb67cf37e]
>>> /usr/lib/libgtk-x11-2.0.so.0(_gtk_marshal_BOOLEAN__BOXED+0x58)
>>> [0xb6c6c02c]
>>> /usr/lib/libgobject-2.0.so.0(g_closure_invoke+0x11e) [0xb697b3a8]
>>> /usr/lib/libgobject-2.0.so.0 [0xb6989c9f]
>>> /usr/lib/libgobject-2.0.so.0(g_signal_emit_valist+0x41e) [0xb698aec3]
>>> /usr/lib/libgobject-2.0.so.0(g_signal_emit+0x29) [0xb698b4c3]
>>> /usr/lib/libgtk-x11-2.0.so.0 [0xb6d4e16f]
>>> /usr/lib/libgtk-x11-2.0.so.0(gtk_main_do_event+0x4f7) [0xb6c6ad72]
>>> /usr/lib/libgdk-x11-2.0.so.0 [0xb6ae6bfa]
>>> /usr/lib/libgdk-x11-2.0.so.0(gdk_window_process_all_updates+0x95)
>>> [0xb6ae6ccd]
>>> /usr/lib/libgdk-x11-2.0.so.0 [0xb6ae6d4e]
>>> /usr/lib/libglib-2.0.so.0 [0xb7f0d750]
>>> /usr/lib/libglib-2.0.so.0(g_main_context_dispatch+0x1dc) [0xb7f0b4ee]
>>> /usr/lib/libglib-2.0.so.0 [0xb7f0e4f6]
>>> /usr/lib/libglib-2.0.so.0(g_main_loop_run+0x1a1) [0xb7f0e7e3]
>>> /usr/lib/libgtk-x11-2.0.so.0(gtk_main+0xb4) [0xb6c69e65]
>>> [0xb67cf6a1]
>>> [0xb67cf660]
>>> [0xb74d2f12]
>>> [0xb74d2813]
>>> mono(mono_runtime_exec_main+0x52) [0x8090ae2]
>>> mono(mono_runtime_run_main+0x12f) [0x80934ef]
>>> mono(mono_main+0xeff) [0x805d26f]
>>> /lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xd2) [0xb7d7bea2]
>>> mono [0x805be11]
>>> _______________________________________________
>>> Mono-devel-list mailing list
>>> Mono-devel-list at lists.ximian.com
>>> http://lists.ximian.com/mailman/listinfo/mono-devel-list
>>>
>> _______________________________________________
>> Mono-devel-list mailing list
>> Mono-devel-list at lists.ximian.com
>> http://lists.ximian.com/mailman/listinfo/mono-devel-list
>>
>
>
> ------------------------------------------------------------------------
>
> Index: Cairo.cs
> ===================================================================
> --- Cairo.cs (revision 52380)
> +++ Cairo.cs (working copy)
> @@ -110,12 +110,13 @@
>
> [DllImport (CairoImp)]
> public static extern void cairo_rotate (IntPtr cr, double angle);
> -
> +
> + // TODO out keyword necessary?
> [DllImport (CairoImp)]
> - public static extern void cairo_transform (IntPtr cr, out Matrix_T matrix);
> + public static extern void cairo_transform (IntPtr cr, out Matrix matrix);
>
> [DllImport (CairoImp)]
> - public static extern void cairo_set_matrix (IntPtr cr, Matrix_T matrix);
> + public static extern void cairo_set_matrix (IntPtr cr, ref Matrix matrix);
>
> [DllImport (CairoImp)]
> public static extern void cairo_identity_matrix (IntPtr cr);
> @@ -223,7 +224,7 @@
>
> [DllImport (CairoImp)]
> public static extern void cairo_set_font_matrix (IntPtr cr,
> - Matrix_T matrix);
> + ref Matrix matrix);
>
> [DllImport (CairoImp)]
> public static extern void cairo_show_text (IntPtr cr, string utf8);
> @@ -305,7 +306,7 @@
> public static extern double cairo_get_miter_limit (IntPtr cr);
>
> [DllImport (CairoImp)]
> - public static extern void cairo_get_matrix (IntPtr cr, Matrix_T matrix);
> + public static extern void cairo_get_matrix (IntPtr cr, ref Matrix matrix);
>
> [DllImport (CairoImp)]
> public static extern IntPtr cairo_get_target (IntPtr cr);
> @@ -382,52 +383,52 @@
> //
>
> [DllImport (CairoImp)]
> - public static extern void cairo_matrix_init (ref Matrix_T matrix,
> + public static extern void cairo_matrix_init (ref Matrix matrix,
> double xx, double yx, double xy, double yy, double x0, double y0);
>
> [DllImport (CairoImp)]
> - public static extern void cairo_matrix_init_translate (ref Matrix_T matrix,
> + public static extern void cairo_matrix_init_translate (ref Matrix matrix,
> double tx, double ty);
>
> [DllImport (CairoImp)]
> - public static extern void cairo_matrix_translate (ref Matrix_T matrix,
> + public static extern void cairo_matrix_translate (ref Matrix matrix,
> double tx, double ty);
>
> [DllImport (CairoImp)]
> - public static extern void cairo_matrix_init_identity (ref Matrix_T matrix);
> + public static extern void cairo_matrix_init_identity (ref Matrix matrix);
>
> [DllImport (CairoImp)]
> - public static extern void cairo_matrix_init_scale (ref Matrix_T matrix,
> + public static extern void cairo_matrix_init_scale (ref Matrix matrix,
> double sx,
> double sy);
>
> [DllImport (CairoImp)]
> - public static extern void cairo_matrix_scale (ref Matrix_T matrix,
> + public static extern void cairo_matrix_scale (ref Matrix matrix,
> double sx,
> double sy);
>
> [DllImport (CairoImp)]
> public static extern void cairo_matrix_init_rotate (
> - ref Matrix_T matrix, double radians);
> + ref Matrix matrix, double radians);
>
> [DllImport (CairoImp)]
> public static extern void cairo_matrix_rotate (
> - ref Matrix_T matrix, double radians);
> + ref Matrix matrix, double radians);
>
> [DllImport (CairoImp)]
> - public static extern Cairo.Status cairo_matrix_invert (ref Matrix_T matrix);
> + public static extern Cairo.Status cairo_matrix_invert (ref Matrix matrix);
>
> [DllImport (CairoImp)]
> public static extern void cairo_matrix_multiply (
> - ref Matrix_T result, ref Matrix_T a, ref Matrix_T b);
> + ref Matrix result, ref Matrix a, ref Matrix b);
>
> [DllImport (CairoImp)]
> public static extern void cairo_matrix_transform_distance (
> - ref Matrix_T matrix, ref double dx, ref double dy);
> + ref Matrix matrix, ref double dx, ref double dy);
>
> [DllImport (CairoImp)]
> public static extern void cairo_matrix_transform_point (
> - ref Matrix_T matrix, ref double x, ref double y);
> + ref Matrix matrix, ref double x, ref double y);
>
> //
> // Pattern functions
> @@ -469,10 +470,10 @@
> double offset, double red, double green, double blue);
>
> [DllImport (CairoImp)]
> - public static extern Status cairo_pattern_set_matrix (IntPtr pattern, IntPtr matrix);
> + public static extern Status cairo_pattern_set_matrix (IntPtr pattern, ref Matrix matrix);
>
> [DllImport (CairoImp)]
> - public static extern Status cairo_pattern_get_matrix (IntPtr pattern, IntPtr matrix);
> + public static extern Status cairo_pattern_get_matrix (IntPtr pattern, ref Matrix matrix);
>
> [DllImport (CairoImp)]
> public static extern Status cairo_pattern_set_extend (IntPtr pattern, Extend extend);
> Index: Pattern.cs
> ===================================================================
> --- Pattern.cs (revision 52380)
> +++ Pattern.cs (working copy)
> @@ -132,17 +132,13 @@
> public Matrix Matrix {
> set {
> CairoAPI.cairo_pattern_set_matrix (pattern,
> - value.Raw);
> + ref value);
> }
>
> get {
> - Matrix_T matrix = new Matrix_T ();
> - IntPtr p = Marshal.AllocCoTaskMem ( Marshal.SizeOf (matrix));
> - Marshal.StructureToPtr (matrix, p, true);
> - CairoAPI.cairo_pattern_get_matrix (pattern, p);
> - matrix = (Matrix_T)Marshal.PtrToStructure(p, typeof(Matrix_T));
> - Marshal.FreeCoTaskMem (p);
> - return new Cairo.Matrix (matrix);
> + Matrix m = new Matrix ();
> + CairoAPI.cairo_pattern_get_matrix (pattern, ref m);
> + return m;
> }
> }
>
> Index: Graphics.cs
> ===================================================================
> --- Graphics.cs (revision 52380)
> +++ Graphics.cs (working copy)
> @@ -527,13 +527,13 @@
>
> public Cairo.Matrix Matrix {
> set {
> - CairoAPI.cairo_set_matrix (state, value.Pointer);
> + CairoAPI.cairo_set_matrix (state, ref value);
> }
>
> get {
> - Matrix_T m = new Matrix_T ();
> - CairoAPI.cairo_get_matrix (state, m);
> - return new Matrix (m);
> + Matrix m = new Matrix ();
> + CairoAPI.cairo_get_matrix (state, ref m);
> + return m;
> }
> }
> /*
> @@ -560,7 +560,7 @@
>
> public void FontSetMatrix (Matrix m)
> {
> - CairoAPI.cairo_set_font_matrix (state, m.Pointer);
> + CairoAPI.cairo_set_font_matrix (state, ref m);
> }
>
> /*
> Index: Matrix.cs
> ===================================================================
> --- Matrix.cs (revision 52380)
> +++ Matrix.cs (working copy)
> @@ -33,118 +33,108 @@
> using System.Runtime.InteropServices;
>
> namespace Cairo {
> -
> -
> - [StructLayout(LayoutKind.Sequential)]
> - internal struct Matrix_T
> - {
> - public double xx;
> - public double yx;
> - public double xy;
> - public double yy;
> - public double x0;
> - public double y0;
> - }
> -
> -
> -
> - public class Matrix
> +
> + [StructLayout(LayoutKind.Sequential)]
> + public struct Matrix
> {
> - internal Matrix_T matrix;
> -
> - public Matrix ()
> + public double xx;
> + public double yx;
> + public double xy;
> + public double yy;
> + public double x0;
> + public double y0;
> +
> +
> + public Matrix (double xx, double yx, double xy, double yy,
> + double x0, double y0)
> {
> - //CreateIdentify();
> + this.xx = xx; this.yx = yx; this.xy = xy;
> + this.yy = yy; this.x0 = x0; this.y0 = y0;
> }
> -
> - internal Matrix (Matrix_T ptr)
> - {
> - //if (ptr == null)
> - // CreateIdentify ();
> -
> - matrix = ptr;
> - }
> -
> - public void CreateIdentify ()
> +
> + public static Matrix Identity {
> + get {
> + Matrix identity = new Matrix ();
> + identity.InitIdentity();
> + return identity;
> + }
> + }
> +
> + public void InitIdentity ()
> {
> - CairoAPI.cairo_matrix_init_identity (ref matrix);
> + CairoAPI.cairo_matrix_init_identity (ref this);
> }
>
> - public void Init (double xx, double yx, double xy, double yy,
> + public Matrix Init (double xx, double yx, double xy, double yy,
> double x0, double y0)
> {
> - matrix.xx = xx; matrix.yx = yx; matrix.xy = xy;
> - matrix.yy = yy; matrix.x0 = x0; matrix.y0 = y0;
> + this.xx = xx; this.yx = yx; this.xy = xy;
> + this.yy = yy; this.x0 = x0; this.y0 = y0;
> + return this;
> }
>
> - public void InitTranslate (double tx, double ty)
> + public Matrix InitTranslate (double tx, double ty)
> {
> - CairoAPI.cairo_matrix_init_translate (ref matrix, tx, ty);
> + CairoAPI.cairo_matrix_init_translate (ref this, tx, ty);
> + return this;
> }
>
> - public void Translate (double tx, double ty)
> + public Matrix Translate (double tx, double ty)
> {
> - CairoAPI.cairo_matrix_translate (ref matrix, tx, ty);
> + CairoAPI.cairo_matrix_translate (ref this, tx, ty);
> + return this;
> }
>
> - public void InitScale (double sx, double sy)
> + public Matrix InitScale (double sx, double sy)
> {
> - CairoAPI.cairo_matrix_init_scale (ref matrix, sx, sy);
> + CairoAPI.cairo_matrix_init_scale (ref this, sx, sy);
> + return this;
> }
>
> - public void Scale (double sx, double sy)
> + public Matrix Scale (double sx, double sy)
> {
> - CairoAPI.cairo_matrix_scale (ref matrix, sx, sy);
> + CairoAPI.cairo_matrix_scale (ref this, sx, sy);
> + return this;
> }
>
> - public void InitRotate (double radians)
> + public Matrix InitRotate (double radians)
> {
> - CairoAPI.cairo_matrix_init_rotate (ref matrix, radians);
> + CairoAPI.cairo_matrix_init_rotate (ref this, radians);
> + return this;
> }
>
> - public void Rotate (double radians)
> + public Matrix Rotate (double radians)
> {
> - CairoAPI.cairo_matrix_rotate (ref matrix, radians);
> + CairoAPI.cairo_matrix_rotate (ref this, radians);
> + return this;
> }
>
> public Cairo.Status Invert ()
> {
> - return CairoAPI.cairo_matrix_invert (ref matrix);
> + return CairoAPI.cairo_matrix_invert (ref this);
> }
>
> -
> - public static void Multiply (ref Cairo.Matrix res,
> - ref Cairo.Matrix a, ref Cairo.Matrix b)
> - {
> - if (res == null)
> - res = new Matrix ();
> -
> - CairoAPI.cairo_matrix_multiply (ref res.matrix,
> - ref a.matrix,
> - ref b.matrix);
> - }
> + public Matrix Multiply (ref Cairo.Matrix b) {
> + Matrix result = new Matrix ();
> + CairoAPI.cairo_matrix_multiply (ref result, ref this, ref b);
> + return (result);
> + }
>
> public void TransformDistance (ref double dx, ref double dy)
> {
> - CairoAPI.cairo_matrix_transform_distance (ref matrix, ref dx, ref dy);
> + CairoAPI.cairo_matrix_transform_distance (ref this, ref dx, ref dy);
> }
>
> public void TransformPoint (ref double x, ref double y)
> {
> - CairoAPI.cairo_matrix_transform_point (ref matrix, ref x, ref y);
> + CairoAPI.cairo_matrix_transform_point (ref this, ref x, ref y);
> }
> -
> - internal Matrix_T Pointer {
> - get { return matrix; }
> - set { matrix = value; }
> - }
> -
> - public IntPtr Raw {
> - get {
> - IntPtr p = Marshal.AllocCoTaskMem ( Marshal.SizeOf (matrix));
> - Marshal.StructureToPtr (matrix, p, true);
> - return p;
> - }
> +
> + public override String ToString ()
> + {
> + String s = String.Format ("xx:{0:##0.0#} xy:{1:##0.0#} yy:{2:##0.0#} yx:{3:##0.0#} x0:{4:##0.0#} y0:{5:##0.0#}",
> + this.xx, this.xy, this.yy, this.yx, this.x0, this.y0);
> + return s;
> }
>
> }
>
> ------------------------------------------------------------------------
>
> _______________________________________________
> Mono-devel-list mailing list
> Mono-devel-list at lists.ximian.com
> http://lists.ximian.com/mailman/listinfo/mono-devel-list
>
More information about the Mono-devel-list
mailing list