in reply to Re^2: Getting segfaults when destroying and recreating Tk box
in thread Getting segfaults when destroying and recreating Tk box

I suspect there is something nasty happening when you re-enter abort_routine. You could add:

my $inAbort;

at the top of the script and change abort_routine to:

sub abort_routine { return if $inAbort; $inAbort = 1; debug("+abort_routine"); debug("abort_routine Array_Index: $Array_Index"); # DO SOMETHING USEFUL HERE TO CLEAN UP THE PROCESS $MW->destroy(); debug("-abort_routine"); }

so that abort_routine is not re-entered during the destroy or (probably better) change the button command to initiate a different sub that just performs $MW->destroy ();:

... $button = $MW->Button( -text => "Shutdown and close", -command => [ \&do_close ] )->pack( -side => 'bottom' ); ... sub abort_routine { debug("+abort_routine"); debug("abort_routine Array_Index: $Array_Index"); # DO SOMETHING USEFUL HERE TO CLEAN UP THE PROCESS debug("-abort_routine"); } sub do_close { $MW->destroy(); }

DWIM is Perl's answer to Gödel

Replies are listed 'Best First'.
Re^4: Getting segfaults when destroying and recreating Tk box
by skt (Initiate) on Sep 05, 2007 at 03:25 UTC
    Thanks again... I've followed your suggestions and learned something, but not solved the problem.

    If I use the original code (above) and simply remove the $MW->destroy() call from abort_routine, the segmentation fault disappears. Each time I click the button, the abort_routine gets called again, but of course without the $MW->destroy, the box never closes and the programme never exits.

    When I modify the abort_routine code to include the counter you suggested and test for non-zero at the outset, the segmentation fault still happens as soon as I try and destroy the box. Also, if I replace abort_routine with a do_close which contains only the $MW->destroy, I also get the segmentation fault.

    I've also tried using an alternate handle for the second box ($MW2), but I still get the segfault.

    It seems that its the second call to $MW->destroy that's doing the damage. Is there something I need to do to clean-up after the first call???

    Thanks,
    Stefan

      I've sort of run out of ideas, especially as I've not actually seen the problem! However $mw->OnDestroy and Dialog Box may be of some help.


      DWIM is Perl's answer to Gödel
        After all of that, I have 'solved' the problem - but in truth, this is not a solution. The behaviour is bizarre. I'd not have found this without the feedback above - so thankyou - but I'm still at a loss to understand whats going on. Let me describe.

        In playing around, I found that I can provoke segmentation faults on my stock-standard Fedora-7 system by simply adding or removing a comment. See below.

        #!/usr/bin/perl -w use Tk; use strict; my $MW; my $Array_Index=""; my @Widget_List; my $Abort_Has_Run; MAIN: { debug("+MAIN"); my $my_ref; my @file_references ; my $i; $MW = MainWindow->new; $Abort_Has_Run = 0 ; push @Widget_List, $MW->title("test box 1"); push @Widget_List, $MW->Label(-text=>"Choose one option", -font=>"courierfont") -> pack; @file_references = ("Ref1", "Ref2", "Ref3", "Ref4"); $i=1; foreach $my_ref (@file_references) { push @Widget_List, $MW->Button(-text => "$my_ref", -command => [ \&do_button, "$my_ref,$i"]) -> pack; $i++; } MainLoop(); debug ("-MAIN"); } sub do_button { my $params; my $widget; debug("+do_button"); $params = shift; (my $ref, $Array_Index) = split (/,/,$params); debug("do_button Array_Index: $Array_Index"); # DO SOMETHING USEFUL HERE TO START A PROCESS # $MW->Label(-text=>"This line will cause a segfault") -> pack; foreach $widget (@Widget_List) { $widget->destroy(); } $MW->Button(-text => "Shutdown and close", -command => [ \&abort_routine]) -> pack; $MW->OnDestroy([\&abort_routine]); debug("-do_button"); } sub abort_routine { return if $Abort_Has_Run == 1 ; $Abort_Has_Run = 1 ; debug("+abort_routine"); # DO SOMETHING USEFUL HERE TO CLEAN UP THE PROCESS $MW->destroy(); debug("-abort_routine"); } sub debug { my @msg = shift; print @msg, "\n"; }
        If I run the code as above, I repeatedly provoke a segmentation fault. Notice that there is a line which is commented out as such.
        # $MW->Label(-text=>"This line will cause a segfault") -> pack;
        If I REMOVE the comment on this line, the code DOES NOT segfault. However if I comment the line out, I get a segfault EVERY TIME.

        Que? What gives??
        Stefan