in reply to Getting segfaults when destroying and recreating Tk box

When I run that code I see a window with 4 buttons and text propmting me to "Choose on option". If I click any button I get a smaller window containing the text

This is the second box Index = 1

and a single button ("Shutdown and close"). At this point the console shows:

+MAIN +do_button do_button Array_Index: 1 -do_button ==MAIN - the first box has been closed

When I click the shutdown button the window closes and the following additional text is generated:

abort_routine Array_Index: 1 +abort_routine abort_routine Array_Index: 1 -abort_routine -abort_routine -MAIN

No errors nor unusual behavior occur. $Tk::VERSION is 804.027 and Perl -v reports 'This is perl, v5.8.7 built for MSWin32-x86-multi-thread'.


DWIM is Perl's answer to Gödel

Replies are listed 'Best First'.
Re^2: Getting segfaults when destroying and recreating Tk box
by skt (Initiate) on Sep 05, 2007 at 02:35 UTC
    Thanks for your comment....
    When I click the shutdown button the window closes and the following additional text is generated:
    abort_routine Array_Index: 1
    +abort_routine
    abort_routine Array_Index: 1
    -abort_routine
    -abort_routine
    -MAIN
    I get a different series of responses than you....

    Firstly when I run the code and the first box opens...

    +MAIN
    Then when I click on something in the first box...
    +do_button do_button Array_Index: 1 -do_button ==MAIN - the first box has been closed
    Then in the last box, when I click on the "shutdown and close" button...
    +abort_routine abort_routine Array_Index: 1 Segmentation fault
    Alternately, if I slimply click the close box, I instead see...
    Segmentation fault
    You see this is quite different from your response, ending in a segfault. But I notice you're using windows and I'm using Linux.

    I'm running Fedora 7, perl -v says "This is perl, v5.8.8 built for x86_64-linux-thread-multi", the Tk rpm which is installed is tk-8.4.13-5.fc7.src.rpm from the livna rpm repository.

    Is there any other info from me that would help work out what is going on?

      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
        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