Re: $drawing_area->queue_draw(); make program crash on some systems



I think I found the problem (or at least a workaround).

If the Cairo context $cr in the expose_event sub is a global variable, I get an X error crash. If I set it to 
be local to the sub, as in the code at the end of this message, I don't get an X error anymore, and a 
consistent behaviour across systems.

I can live with that, but am still wondering why I get an error if $cr is global... 

Also in case it helps and for future reference, I was able to get some backtrace by breaking on _XError:

gdb --args perl mini.pl --sync
...
(gdb) break _XError
...
(gdb) run
...

Breakpoint 1, 0x00007ffff5479230 in _XError () from /usr/lib64/libX11.so.6
(gdb) bt
#0  0x00007ffff5479230 in _XError () from /usr/lib64/libX11.so.6
#1  0x00007ffff54763d7 in ?? () from /usr/lib64/libX11.so.6
#2  0x00007ffff5476485 in ?? () from /usr/lib64/libX11.so.6
#3  0x00007ffff5477380 in _XReply () from /usr/lib64/libX11.so.6
#4  0x00007ffff5472ebd in XSync () from /usr/lib64/libX11.so.6
#5  0x00007ffff5472f4b in ?? () from /usr/lib64/libX11.so.6
#6  0x00007ffff5479c6f in ?? () from /usr/lib64/libX11.so.6
#7  0x00007ffff545679a in XCreateGC () from /usr/lib64/libX11.so.6
#8  0x00007ffff6c0d668 in ?? () from /usr/lib64/libcairo.so.2
#9  0x00007ffff6c10a6d in ?? () from /usr/lib64/libcairo.so.2
#10 0x00007ffff6c13a12 in ?? () from /usr/lib64/libcairo.so.2
#11 0x00007ffff6c105b9 in ?? () from /usr/lib64/libcairo.so.2
#12 0x00007ffff6be2c9f in cairo_surface_flush () from 
/usr/lib64/libcairo.so.2
#13 0x00007ffff023f169 in ?? () from /usr/lib64/libgdk-x11-2.0.so.0
#14 0x00007ffff6b8d061 in ?? () from /usr/lib64/libcairo.so.2
#15 0x00007ffff6ba2229 in ?? () from /usr/lib64/libcairo.so.2
#16 0x00007ffff6ea73d9 in XS_Cairo__Context_DESTROY ()
   from 
/usr/lib/perl5/vendor_perl/5.18.1/x86_64-linux-thread-multi/auto/Cairo/Cairo.so
#17 0x00000000004ab506 in Perl_pp_entersub ()
#18 0x0000000000437257 in Perl_call_sv ()
#19 0x00000000004b43f6 in ?? ()
#20 0x00000000004b4b20 in Perl_sv_clear ()

Cheers,

Guillaume

-------------------- mini.pl with no crash follows ----------------------------

#!/usr/bin/perl -w

use warnings;
use strict;
use Cairo;
use Glib qw/TRUE FALSE/;
use Gtk2;

## set $case=0 to produces immediate crash on opensuse 13.1 x86_64
## set $case=1 to produces crash after a few clicks on drawing area on opensuse 13.1 x86_64
## both $case=0 and $case=1 produce no crash on opensuse 13.1 i586, nor on windows.
my $case=0;

my $window = undef;
my $drawing_area = undef;
my $ScrolledWindow = undef;
my $surface = undef;

$surface = Cairo::ImageSurface->create('rgb24',200,200);
my $cr = Cairo::Context->create( $surface );
$cr->rectangle (0,0,200,200);
$cr->set_source_rgb (1,1,1);
$cr->fill;
$cr->show_page;

Gtk2->init;

$window = Gtk2::Window->new ('toplevel');
$window->set_size_request(200,200);
$window->signal_connect ("destroy", sub { Gtk2->main_quit });

$drawing_area = Gtk2::DrawingArea->new;

if($case==0){
  $drawing_area->set_size_request (200,200);
  $window->add ($drawing_area);
}else{
  my $hbox=createmaindrawingarea();
  $window->add($hbox);
}

$drawing_area->signal_connect (expose_event => \&expose_event);

$window->show_all;

Gtk2->main;

sub expose_event {
  my $widget = shift; 
  # removing the "my" produces an X error on some systems
  my $cr = Gtk2::Gdk::Cairo::Context->create( $widget->window );
  $cr->set_source_surface( $surface, 0, 0 ); 
  $cr->paint;
  return FALSE;
}


sub createmaindrawingarea {

my $hbox = Gtk2::HBox->new (FALSE, 0);
$hbox->set_border_width(5);

my $vp = Gtk2::Viewport->new( undef, undef );
$ScrolledWindow = Gtk2::ScrolledWindow->new(undef, undef );
$ScrolledWindow->set_policy( 'automatic', 'automatic' );
$ScrolledWindow->add( $vp );

$drawing_area = Gtk2::DrawingArea->new;
$drawing_area->set_size_request (2000,2000);

$vp->add($drawing_area);
$hbox->pack_start ($ScrolledWindow, TRUE, TRUE, 0);

$drawing_area->signal_connect (expose_event => \&expose_event);
$drawing_area->signal_connect (button_press_event => \&button_press_event);
$drawing_area->set_events ([qw/button-press-mask/]);
$drawing_area->set_extension_events("cursor");

return $hbox;

}

sub button_press_event {
  $drawing_area->queue_draw();
}





[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]