Bug #51093 [Fbk->Opn]: segfault with signal_autoconnect function of class GladeXML

[email protected] ("jboffel at gmail dot com") Fri, 30 Apr 2010 10:02:20 +0200 (CEST)
Newsgroups php.gtk.dev
Message-ID <[email protected]>
Edit report at http://bugs.php.net/bug.php?id=51093&edit=1

 ID:               51093
 User updated by:  jboffel at gmail dot com
 Reported by:      jboffel at gmail dot com
 Summary:          segfault with signal_autoconnect function of class
                   GladeXML
-Status:           Feedback
+Status:           Open
 Type:             Bug
 Package:          PHP-GTK related
 Operating System: any GNU/Linux at least
 PHP Version:      5.2.12
 Assigned To:      kalle

 New Comment:

Yes it's working with my code

Thanks


Previous Comments:
------------------------------------------------------------------------
[2010-04-05 00:45:50] [email protected]

Can you confirm the attached patched .overrides file works with your
code?

------------------------------------------------------------------------
[2010-04-05 00:44:36] [email protected]

The following patch has been added/updated:

Patch Name: gtk-signal-autoconnect-overrides
Revision:   1270421076
URL:       
http://bugs.php.net/patch-display.php?bug=51093&patch=gtk-signal-autoconnect-overrides&revision=1270421076

------------------------------------------------------------------------
[2010-02-20 01:03:37] jboffel at gmail dot com

Ok sorry fix is :

if(map)
    zval_copy_ctor(map);

Else we have a segfault when no parameter is given...

------------------------------------------------------------------------
[2010-02-19 19:45:33] jboffel at gmail dot com

Description:
------------
PHP-GTK2 last stable version : 2.0.1

I found a case you can have a segfault by using signal_autoconnect
function of class GaldeXML of php-gtk2 extension.

The code example below just create a single window with 2 buttons.

Click on Refresh button is supposed to print the result of phpinfo() in
a textarea.

But when you do so, sometimes you'll get a segfault or a fatal error
about a too large amount of memory requested during one allocation.

I identified the problem, no copy are done of the optional parameter
given to signal_autoconnect function. So right after using the function,
the array given in parameter is detroyed as nobody still have a
reference on it. And so it's no more available when the signal callback
function is executed...

You can add this line in file: php-gtk-2.0.1/ext/libglade/gen_libglade.c
on line: 351

zval_copy_ctor(map);

It worked for me as expected.
It could be claimed that it's not a bug as you can create a variable
previously and give it as parameter to the function, that would do the
job, but if any modification and/or unset are done before data are used,
the result will be unexpected for sure. I can't think it's the expected
behavior.

Reproduce code:
---------------
Main code :

<?php
$glade = new GladeXML(dirname(__FILE__) . '/helloglade.glade');
$glade->signal_autoconnect(array(
                'on_Refresh_clicked'=>array(NULL, $glade)
        ));
function on_Refresh_clicked($button, $glade) {
        $phpinfo_window=$glade->get_widget('phpinfo_window');
        $textBuffer = new GtkTextBuffer();
        ob_start () ;
        phpinfo () ;
        $pinfo = ob_get_contents () ;
        ob_end_clean () ;
        $textBuffer->set_text($pinfo);
        $phpinfo_window->set_buffer($textBuffer);
}
function gtk_main_quit() {
        Gtk::main_quit();
}
Gtk::main();
?>

Find here my helloglade.glade file auto-generated by gnome glade
interface:

<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
<!DOCTYPE glade-interface SYSTEM
"http://glade.gnome.org/glade-2.0.dtd">

<glade-interface>

<widget class="GtkWindow" id="main">
  <property name="visible">True</property>
  <property name="title" translatable="yes">phpinfo()</property>
  <property name="type">GTK_WINDOW_TOPLEVEL</property>
  <property name="window_position">GTK_WIN_POS_NONE</property>
  <property name="modal">False</property>
  <property name="default_width">700</property>
  <property name="default_height">500</property>
  <property name="resizable">True</property>
  <property name="destroy_with_parent">True</property>
  <property name="decorated">True</property>
  <property name="skip_taskbar_hint">False</property>
  <property name="skip_pager_hint">False</property>
  <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
  <property name="focus_on_map">True</property>
  <property name="urgency_hint">False</property>
  <accessibility>
    <atkproperty name="AtkObject::accessible_name"
translatable="yes">main</atkproperty>
  </accessibility>

  <child>
    <widget class="GtkVBox" id="vbox1">
      <property name="visible">True</property>
      <property name="homogeneous">False</property>
      <property name="spacing">0</property>

      <child>
        <widget class="GtkScrolledWindow" id="scrolledwindow1">
          <property name="visible">True</property>
          <property name="can_focus">True</property>
          <property
name="hscrollbar_policy">GTK_POLICY_NEVER</property>
          <property
name="vscrollbar_policy">GTK_POLICY_NEVER</property>
          <property name="shadow_type">GTK_SHADOW_IN</property>
          <property
name="window_placement">GTK_CORNER_TOP_LEFT</property>

          <child>
            <widget class="GtkViewport" id="viewport1">
              <property name="visible">True</property>
              <property name="shadow_type">GTK_SHADOW_IN</property>

              <child>
                <widget class="GtkTable" id="table1">
                  <property name="visible">True</property>
                  <property name="n_rows">2</property>
                  <property name="n_columns">1</property>
                  <property name="homogeneous">False</property>
                  <property name="row_spacing">0</property>
                  <property name="column_spacing">0</property>

                  <child>
                    <widget class="GtkScrolledWindow"
id="scrolledwindow2">
                      <property name="visible">True</property>
                      <property name="can_focus">True</property>
                      <property
name="hscrollbar_policy">GTK_POLICY_ALWAYS</property>
                      <property
name="vscrollbar_policy">GTK_POLICY_ALWAYS</property>
                      <property
name="shadow_type">GTK_SHADOW_IN</property>
                      <property
name="window_placement">GTK_CORNER_TOP_LEFT</property>

                      <child>
                        <widget class="GtkTextView"
id="phpinfo_window">
                          <property name="visible">True</property>
                          <property name="can_focus">True</property>
                          <property name="editable">True</property>
                          <property name="overwrite">False</property>
                          <property name="accepts_tab">True</property>
                          <property
name="justification">GTK_JUSTIFY_LEFT</property>
                          <property
name="wrap_mode">GTK_WRAP_NONE</property>
                          <property
name="cursor_visible">True</property>
                          <property
name="pixels_above_lines">0</property>
                          <property
name="pixels_below_lines">0</property>
                          <property
name="pixels_inside_wrap">0</property>
                          <property name="left_margin">0</property>
                          <property name="right_margin">0</property>
                          <property name="indent">0</property>
                          <property name="text"
translatable="yes"></property>
                        </widget>
                      </child>
                    </widget>
                    <packing>
                      <property name="left_attach">0</property>
                      <property name="right_attach">1</property>
                      <property name="top_attach">1</property>
                      <property name="bottom_attach">2</property>
                      <property name="x_options">fill</property>
                    </packing>
                  </child>

                  <child>
                    <widget class="GtkLabel" id="label1">
                      <property name="visible">True</property>
                      <property name="label" translatable="yes">Contenu
du résultat de phpinfo :</property>
                      <property name="use_underline">False</property>
                      <property name="use_markup">False</property>
                      <property
name="justify">GTK_JUSTIFY_LEFT</property>
                      <property name="wrap">False</property>
                      <property name="selectable">False</property>
                      <property name="xalign">0</property>
                      <property name="yalign">0.5</property>
                      <property name="xpad">0</property>
                      <property name="ypad">0</property>
                      <property
name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
                      <property name="width_chars">-1</property>
                      <property
name="single_line_mode">False</property>
                      <property name="angle">0</property>
                    </widget>
                    <packing>
                      <property name="left_attach">0</property>
                      <property name="right_attach">1</property>
                      <property name="top_attach">0</property>
                      <property name="bottom_attach">1</property>
                      <property name="y_options"></property>
                    </packing>
                  </child>
                </widget>
              </child>
            </widget>
          </child>
        </widget>
        <packing>
          <property name="padding">0</property>
          <property name="expand">True</property>
          <property name="fill">True</property>
        </packing>
      </child>

      <child>
        <widget class="GtkHButtonBox" id="hbuttonbox1">
          <property name="visible">True</property>
          <property
name="layout_style">GTK_BUTTONBOX_DEFAULT_STYLE</property>
          <property name="spacing">0</property>

          <child>
            <widget class="GtkButton" id="Close">
              <property name="visible">True</property>
              <property name="can_default">True</property>
              <property name="can_focus">True</property>
              <property name="label">gtk-close</property>
              <property name="use_stock">True</property>
              <property name="relief">GTK_RELIEF_NORMAL</property>
              <property name="focus_on_click">True</property>
              <signal name="clicked" handler="gtk_main_quit"
last_modification_time="Wed, 17 Feb 2010 17:03:35 GMT"/>
            </widget>
          </child>

          <child>
            <widget class="GtkButton" id="Refresh">
              <property name="visible">True</property>
              <property name="can_default">True</property>
              <property name="can_focus">True</property>
              <property name="label"
translatable="yes">Refresh</property>
              <property name="use_underline">True</property>
              <property name="relief">GTK_RELIEF_NORMAL</property>
              <property name="focus_on_click">True</property>
              <signal name="clicked" handler="on_Refresh_clicked"
object="glade" last_modification_time="Wed, 17 Feb 2010 17:03:14 GMT"/>
            </widget>
          </child>
        </widget>
        <packing>
          <property name="padding">0</property>
          <property name="expand">False</property>
          <property name="fill">True</property>
        </packing>
      </child>
    </widget>
  </child>
</widget>

</glade-interface>

Expected result:
----------------
A windows with a textarea showing phpinfo() result.

Actual result:
--------------
segfault / Fatal Error, depending of memory state.


------------------------------------------------------------------------



-- 
Edit this bug report at http://bugs.php.net/bug.php?id=51093&edit=1