php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #51093 segfault with signal_autoconnect function of class GladeXML
Submitted: 2010-02-19 19:45 UTC Modified: 2010-04-30 14:34 UTC
From: jboffel at gmail dot com Assigned: kalle (profile)
Status: Closed Package: PHP-GTK related
PHP Version: 5.2.12 OS: any GNU/Linux at least
Private report: No CVE-ID: None
 [2010-02-19 19:45 UTC] 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.

Patches

gtk-signal-autoconnect-overrides (last revision 2010-04-04 22:44 UTC by kalle@php.net)

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2010-02-20 01:03 UTC] 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-04-05 00:44 UTC] kalle@php.net
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-04-05 00:45 UTC] kalle@php.net
-Status: Open +Status: Feedback -Assigned To: +Assigned To: kalle
 [2010-04-05 00:45 UTC] kalle@php.net
Can you confirm the attached patched .overrides file works with your code?
 [2010-04-30 10:02 UTC] jboffel at gmail dot com
-Status: Feedback +Status: Open
 [2010-04-30 10:02 UTC] jboffel at gmail dot com
Yes it's working with my code

Thanks
 [2010-04-30 14:34 UTC] kalle@php.net
Automatic comment from SVN on behalf of kalle
Revision: http://svn.php.net/viewvc/?view=revision&amp;revision=298805
Log: Fixed bug #51093 (segfault with signal_autoconnect function of class GladeXML) (Kalle, jboffel at gmail dot com)
 [2010-04-30 14:34 UTC] kalle@php.net
-Status: Open +Status: Closed
 [2010-04-30 14:34 UTC] kalle@php.net
This bug has been fixed in SVN.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.
 
Thank you for the report, and for helping us make PHP better.


 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Dec 21 13:01:31 2024 UTC