Skip Menu |

This queue is for tickets about the POE-Loop-Tk CPAN distribution.

Report information
The Basics
Id: 77763
Status: open
Priority: 0/
Queue: POE-Loop-Tk

People
Owner: Nobody in particular
Requestors: capfan [...] gmx.de
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: (no value)
Fixed in: (no value)



Subject: Problem with Tk loop
Date: Mon, 11 Jun 2012 22:29:52 +0200
To: <bug-poe [...] rt.cpan.org>
From: "Alex" <capfan [...] gmx.de>
Dear recipient, I got this of one of my scripts: [quote] please report this stacktrace to bug-poe@rt.cpan.org at C:/Perl/site/lib/POE/Kernel.pm line 1013 POE::Kernel::_dispatch_event('POE::Kernel=ARRAY(0x43a05b4)', undef, 'POE::Kernel=ARRAY(0x43a05b4)', '_child', 128, 'ARRAY(0x4c3c914)', 'C:/Perl/site/lib/POE/Kernel.pm', 1454, undef, ...) called at C:/Perl/site/lib/POE/Kernel.pm line 1452 POE::Kernel::session_alloc('POE::Kernel=ARRAY(0x43a05b4)', 'POE::Session=ARRAY(0x3d93f84)') called at C:/Perl/site/lib/POE/Session.pm line 192 POE::Session::try_alloc('POE::Session=ARRAY(0x3d93f84)') called at C:/Perl/site/lib/POE/Session.pm line 373 POE::Session::create('POE::Session', 'inline_states', 'HASH(0x46944d4)', 'args', 'ARRAY(0x4694664)') called at C:\Perl\Skripten\tk\apache_log_parser\apacheLogParser_tk.pl line 76 === 3420 === Sessions were started, but POE::Kernel's run() method was never called to execute them. This usually happens because an error occurred before POE::Kernel->run() could be called. Please fix any errors above this notice, and be sure that POE::Kernel->run() is called. See documentation for POE::Kernel's run() method for another way to disable this warning. [/quote] I will include the code, too. Here is what I did: I use ActiveState Perl and Tk with POE. My script works fine, unless I add a $poe_main_window->update() statement somewhere before the $kernel-run()-method. Then, it crashed. I tried to get the windows' dimensions live before configuring the Tk::Menu of the window, because if I don't, the window will be display the menu only: HTH, Alex Script (NB: it’s commented in german because it’s intended as instruction script for Germans): #!/Perl/bin/perl =head1 NAME apacheLogParser_tk.pl - ein Programm zum überwachen von Dateien =head1 BESCHREIBUNG Im Quelltext findet sich ein Abschnitt, in dem die zu überwachenden Dateien eingetragen werden können. Diese Dateien werden dann automatisch auf Änderungen geprüft. =head2 VERWENDUNG Die zu überwachenden Dateien in @logdateien eintragen, Programm starten. =cut use strict; use warnings; use Config::Auto; use Data::Dumper qw/Dumper/; use File::Spec; use DBIx::NoSQL; use utf8; use vars qw($VERSION); $VERSION = 0.3; # Tk support is enabled if the Tk module is used before POE itself. use Tk; use Tk::ToolBar; use Tk::StatusBar; # except when it isn't... # # ActiveState does something funky such that if you don't include # Loop::TkActiveState here Loop::Tk won't be detected. The good news # is that it does not appear to be necessary to special case this for # other platforms. use POE qw( Loop::TkActiveState Wheel::FollowTail ); # Datenbank initialisieren, in der die Konfigurationsparameter gespeichert werden. # Die Datenbank wird automatisch erstellt, wenn noch keine vorhanden ist. my $store = DBIx::NoSQL->connect( 'store.sqlite' ); # Definiere globale Variablen zum Programm # ToDo: Konfigurationsdatei verwenden, Dialog zum hinzufügen und Entfernen der # Dateien anlegen. my $logdateien = $store->exists( 'Files', 'watched' ); unless( $logdateien ) { $logdateien = []; } #my $logdateien = [ # File::Spec->catfile(qw(c: Apache logs error.log)), # File::Spec->catfile(qw(c: Apache logs access.log)), #]; # Dubletten entfernen my %seen = (); @{$logdateien} = grep { ! $seen{ $_ }++ } @{$logdateien}; undef %seen; foreach( @{$logdateien} ) { die "Logdatei [$_] existiert nicht!\n" unless -e $_; } # Create the session that will drive the user interface. POE::Session->create( inline_states => { _start => \&ui_start, ev_count => \&ui_count, ev_clear => \&ui_clear, got_line => \&updateLog_line, got_error => \&updateLog_error, }, args => \@{$logdateien}, ); # Run the program until it is exited. $poe_kernel->run(); exit 0; =head2 METHODEN =head3 ui_start Baut die grafische Oberfläche zusammen. Pro angegebene Log-Datei gibt es einen Notebook-Reiter. ToDo: Wenn die Reiter breiter sind als das Fenster sollte ein Scroll-Teil an der Seite erscheinen, oder irgend eine andere Möglichkeit geboten werden auf diese Reiter zuzugreifen. Reiter scheinen sowieso irgendwie ungeeigenet zu sein, einzelne Fenster wären wohl besser. =cut sub ui_start { my ( $kernel, $session, $heap ) = @_[ KERNEL, SESSION, HEAP ]; # -- Fenstergröße ungefähr anpassen die "could not create a main Tk window" unless defined $poe_main_window; $poe_main_window->configure(-width => 1280, -height => 480,); $poe_main_window->packPropagate(0); #$poe_main_window->update(); # -- Menu erstellen my $menuitems = [ [Cascade => "~Datei", -menuitems => [ [Button => "~Neu", -command => \&new], [Separator => ""], [Button => "~Öffnen", -command => \&open], [Button => "~Sichern", -command => \&save], ], ], ]; my $menu = $poe_main_window->Menu(-menuitems => $menuitems); $poe_main_window->configure(-menu => $menu); # -- TK-GUI erstellen require Tk::NoteBook; $heap->{notebook} = $poe_main_window->NoteBook(); foreach my $logdatei ( @{$logdateien} ) { $heap->{notebookSeiten}{$logdatei}{seite} = $heap->{notebook}->add($logdatei, -label => $logdatei,); $heap->{notebookSeiten}{$logdatei}{scr_txt} = $heap->{notebookSeiten}{$logdatei}{seite}->Scrolled( # keine Eigenschaften wie Höhe oder Breite, weil das Textfeld skalierbar sein soll. Text => -scrollbars => 'se', )->pack(-expand => 1, -fill => 'both',); # -- Buttons für Funktionen erstellen $heap->{notebookSeiten}{$logdatei}{btn_frame} = $heap->{notebookSeiten}{$logdatei}{seite}->Frame(); $heap->{notebookSeiten}{$logdatei}{clear_btn} = $heap->{notebookSeiten}{$logdatei}{btn_frame}->Button( -text => 'Anzeige leeren', -command => sub{ $heap->{notebookSeiten}{$logdatei}{scr_txt}->Subwidget('scrolled')->delete(" 0.0", "end"); #print "$logdatei\n"; #print Dumper $heap->{notebookSeiten}{$logdatei}{scr_txt}->Subwidget('scrolled'); # = undef??? }, )->pack(-side => 'left',); $heap->{notebookSeiten}{$logdatei}{btn_frame}->pack(-side => 'left',); } $heap->{notebook}->pack(-expand => 1, -fill => 'both',); # -- Statusbar # -> für den UI-Counter require Tk::StatusBar; $heap->{statusbar} = $poe_main_window->StatusBar(); $heap->{statusbar}->addLabel( -relief => 'flat', -text => "Welcome to the statusbar", ); $heap->{statusbar}->addLabel( -text => 'Frame:', -width => '10', -anchor => 'center', ); $heap->{statusbar}->addLabel( -width => 20, -anchor => 'center', -textvariable => \$heap->{counter}, -foreground => 'blue', ); $heap->{statusbar}->addLabel( -width => 10, -anchor => 'center', -text => "Clear", -foreground => 'blue', -command => $session->postback("ev_clear"), -event => '<Button-1>', ); # -- Wheel erstellen um die Error.log zu überwachen foreach( @{$logdateien} ) { $heap->{wheel}->{$_} = POE::Wheel::FollowTail->new( Filename => $_, InputEvent => 'got_line', ErrorEvent => 'got_error', SeekBack => 1024, ); } $heap->{first} = 0; # Loop starten $kernel->yield("ev_count"); } # /ui_start =head3 ui_count Handle the "ev_count" event by increasing a counter and displaying its new value. =cut sub ui_count { $_[HEAP]->{counter}++; $_[KERNEL]->yield("ev_count"); } # /ui_count =head3 ui_clear Handle the "ev_clear" event by clearing and redisplaying the counter. =cut sub ui_clear { $_[HEAP]->{counter} = 0; } # /ui_clear =head3 updateLog_line Fügt die neuen Informationen aus den zu verfolgenden Dateien im entsprechenden Reiter an. In $_[ARG0] scheint dabei das zu stehen, was bei der gerade modifizierten Datei angehangen wurde und in $_[ARG1] die Nummer (beginnend bei 1) der Datei in der Liste der zu verfolgenden Dateien ( siehe args - Argument bei POE::Session->create() ). Ideen: Flashen der Reiter wenn ein Update erfolgt ist. Automatisches Scrollen als Option (an|aus), umdrehen der einzelnen Datei-Abschnitte (geht z.B. bei Apache-Logdateien) um den aktuellen Eintrage immer oben zu haben. =cut sub updateLog_line { my ( $kernel, $session, $heap ) = @_[ KERNEL, SESSION, HEAP ]; my $eingabe = $_[ARG0]; #print STDERR Dumper $_[ARG0]; my @eingaben = split m/\\r, /, $eingabe; foreach my $eing ( @eingaben ) { $heap->{notebookSeiten}{$logdateien->[($_[ARG1]-1)]}{scr_txt}->insert("end", "normal: $eing\n") if $heap->{first}++; } } # /updateLog_line =head3 updateLog_error Keine Ahnung was das hier macht... =cut sub updateLog_error { warn "$_[ARG0]\n"; } # /pdateLog_error =head2 QUELLEN =over =item * L<http://poe.perl.org/?POE_Cookbook> =over =item a) POE+Tk - Rezept L<http://poe.perl.org/?POE_Cookbook/Tk_Interfaces> =item b) POE+Wheel::FollowTail - Rezept L<http://poe.perl.org/?POE_Cookbook/Watching_Logs> =back =back =head2 AUTOR Alexander Becker, asb_ehb doYouKnowWhatToInsertHere? yahoo.de =head2 SIEHE AUCH =over =item * L<TK> =item * L<POE> =item * L<http://poe.perl.org/?POE_Cookbook/Tk_Interfaces> =item * L<http://www.perl-community.de> =back

Message body is not shown because it is too large.

Download image001.png
image/png 6.6k
image001.png
Here's a smaller version of the test case. It works fine for me, but I'm not using Windows, and both Tk and POE are probably newer than when this bug opened.
Subject: bug-77763.pl
#!perl use warnings; use strict; use Tk; use POE; use POE::Wheel::FollowTail; my $logdateien = [ '/var/log/system.log', '/var/log/kernel.log', '/var/log/windowserver.log', ]; POE::Session->create( inline_states => { _start => \&ui_start, ev_count => \&ui_count, ev_clear => \&ui_clear, got_line => \&updateLog_line, got_error => \&updateLog_error, }, args => \@{$logdateien}, ); POE::Kernel->run(); exit 0; sub ui_start { my ($kernel, $session, $heap) = @_[KERNEL, SESSION, HEAP]; die "could not create a main Tk window" unless defined $poe_main_window; $poe_main_window->configure(-width => 1280, -height => 480,); $poe_main_window->packPropagate(0); $poe_main_window->update(); my $menuitems = [ [ Cascade => "~Datei", -menuitems => [ [Button => "~Neu", -command => \&new], [Separator => ""], [Button => "~Öffnen", -command => \&open], [Button => "~Sichern", -command => \&save], ], ], ]; my $menu = $poe_main_window->Menu(-menuitems => $menuitems); $poe_main_window->configure(-menu => $menu); require Tk::NoteBook; $heap->{notebook} = $poe_main_window->NoteBook(); foreach my $logdatei (@{$logdateien}) { $heap->{notebookSeiten}{$logdatei}{seite} = $heap->{notebook}->add($logdatei, -label => $logdatei,); $heap->{notebookSeiten}{$logdatei}{scr_txt} = $heap->{notebookSeiten}{$logdatei}{seite}->Scrolled( Text => -scrollbars => 'se', )->pack(-expand => 1, -fill => 'both',); $heap->{notebookSeiten}{$logdatei}{btn_frame} = $heap->{notebookSeiten}{$logdatei}{seite}->Frame(); $heap->{notebookSeiten}{$logdatei}{clear_btn} = $heap->{notebookSeiten}{$logdatei}{btn_frame}->Button( -text => 'Anzeige leeren', -command => sub { $heap->{notebookSeiten}{$logdatei}{scr_txt}->Subwidget('scrolled') ->delete(" 0.0", "end"); }, )->pack(-side => 'left',); $heap->{notebookSeiten}{$logdatei}{btn_frame}->pack(-side => 'left',); } $heap->{notebook}->pack(-expand => 1, -fill => 'both',); foreach (@{$logdateien}) { $heap->{wheel}->{$_} = POE::Wheel::FollowTail->new( Filename => $_, InputEvent => 'got_line', ErrorEvent => 'got_error', SeekBack => 1024, ); } $heap->{first} = 0; $kernel->yield("ev_count"); } sub ui_count { $_[HEAP]->{counter}++; $_[KERNEL]->yield("ev_count"); } sub ui_clear { $_[HEAP]->{counter} = 0; } sub updateLog_line { my ($kernel, $session, $heap) = @_[KERNEL, SESSION, HEAP]; my $eingabe = $_[ARG0]; my @eingaben = split m/\\r, /, $eingabe; foreach my $eing (@eingaben) { $heap->{notebookSeiten}{$logdateien->[($_[ARG1] - 1)]}{scr_txt} ->insert("end", "normal: $eing\n") if $heap->{first}++; } } sub updateLog_error { warn "$_[ARG0]\n"; }
Am Mi 21. Aug 2013, 20:00:38, RCAPUTO schrieb: Show quoted text
> Here's a smaller version of the test case. It works fine for me, but > I'm not using Windows, and both Tk and POE are probably newer than > when this bug opened.
Hi! I checked again, with Perl/Tk version 804.031 and POE 1.356 on WIndows 8 x64 with v5.16.3 x86 from ActiveState. The error still occurs if $poe_main_window->update(); is called. If I comment this line, the application starts, but the window size is of course not adjusted. NB: the error occurs in both cases, when using yout kind of POE use: use POE; use POE::Wheel::FollowTail; and when I use the other variant using POE::Loop::TkActiveState: use POE qw( Loop::TkActiveState Wheel::FollowTail ); Please find atatched the stacktrace. Best regards, Alex
Subject: 2013-08-22-stacktrace.txt
please report this stacktrace to bug-poe@rt.cpan.org at c:/Perl/site/lib/POE/Kernel.pm line 1020. POE::Kernel::_dispatch_event('POE::Kernel=ARRAY(0x2ded8b4)', undef, 'POE::Kernel=ARRAY(0x2ded8b4)', '_child', 128, 'ARRAY(0x393cda4)', 'c:/Perl/site/lib/POE/Kernel.pm', 1463, undef, ...) called at c:/Perl/site/lib/POE/Kernel.pm line 1461 POE::Kernel::session_alloc('POE::Kernel=ARRAY(0x2ded8b4)', 'POE::Session=ARRAY(0x393cb54)', 'D:/Apache/logs/error.log') called at c:/Perl/site/lib/POE/Session.pm line 192 POE::Session::try_alloc('POE::Session=ARRAY(0x393cb54)', 'D:/Apache/logs/error.log') called at c:/Perl/site/lib/POE/Session.pm line 373 POE::Session::create('POE::Session', 'inline_states', 'HASH(0x393caf4)', 'args', 'ARRAY(0x46e4e4)') called at D:\Users\root\Documents\Perl\Skripten\tk\POE\toolbar-test-simpler.pl line 24 === 3464 === Sessions were started, but POE::Kernel's run() method was never called to execute them. This usually happens because an error occurred before POE::Kernel->run() could be called. Please fix any errors above this notice, and be sure that POE::Kernel->run() is called. See documentation for POE::Kernel's run() method for another way to disable this warning.
Okay, I was able to get this to break by upgrading ActivePerl on Windows 7 Professional. This seems to avoid the crash, so it's a clue about the cause: set POE_CATCH_EXCEPTIONS=0 ... however, the program detects child processes at exit.
My previous reply was wrong. The first run after a clean reboot causes a stack trace like the one you appended to this ticket. It seems that the update() call refreshes the window first. Second and subsequent runs don't fail. It's as if a DLL hasn't had a chance to load the first time, but now that it's in memory everything's fine.
Hi! This made me suspicious. Usually, I run the program from my IDE when gettng the error. It's Komodo IDE 9. However, when calling it from command line, it doesn't crash at all. No matter if after a restart of the computer or not. The perl is the same, I checked it (it's always C:\Perl\bin\perl.EXE). Is there some sort of debugging log I could provide you?
Hi again! This is probably a race condition in POE::Loop::TkActiveState. Komodo may be enabling debugging hooks that change execution timing. That could be smoothing over the race condition, or causing different ones to emerge.