From c61516c381d5d6915c8d77e455ce5f707d20c0bb Mon Sep 17 00:00:00 2001 From: Magnus Svensson Date: Mon, 6 Oct 2008 10:49:12 +0200 Subject: [PATCH 1/7] Improve gdb coredump --- mysql-test/lib/My/CoreDump.pm | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/mysql-test/lib/My/CoreDump.pm b/mysql-test/lib/My/CoreDump.pm index 5f7427768c2..513226d1b47 100644 --- a/mysql-test/lib/My/CoreDump.pm +++ b/mysql-test/lib/My/CoreDump.pm @@ -25,6 +25,8 @@ use File::Temp qw/ tempfile tempdir /; sub _gdb { my ($core_name)= @_; + print "\nTrying 'gdb' to get a backtrace\n"; + return unless -f $core_name; my $dir = tempdir( CLEANUP => 1 ); @@ -35,7 +37,7 @@ sub _gdb { "quit\n"; # Find out name of binary that generated core - my $list= `gdb -c $core_name -x $tmp_name -q 2>&1` + my $list= `gdb -c $core_name -x $tmp_name -batch 2>&1` or return; my $binary; @@ -47,9 +49,9 @@ sub _gdb { return unless $binary; - print "Generated by '$binary'\n"; + print " - core generated by '$binary'\n"; - my $list= `gdb $binary -c $core_name -x $tmp_name -q 2>&1` + my $list= `gdb $binary -c $core_name -x $tmp_name -batch 2>&1` or return; print $list, "\n"; From c11b5ddfa80d2c078714d61049aa3712a0ea1d93 Mon Sep 17 00:00:00 2001 From: Magnus Svensson Date: Mon, 6 Oct 2008 19:34:00 +0200 Subject: [PATCH 2/7] WL#4189 add verbose also when starting check testcase --- mysql-test/mysql-test-run.pl | 1 + 1 file changed, 1 insertion(+) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 53f916a630a..b2a074f70b2 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -4210,6 +4210,7 @@ sub start_check_testcase ($$$) { error => $errfile, args => \$args, user_data => $errfile, + verbose => $opt_verbose, ); mtr_report("Started $proc"); From 01a3ac7596627573e5a572a89802d662db373a0b Mon Sep 17 00:00:00 2001 From: Magnus Svensson Date: Mon, 6 Oct 2008 19:51:33 +0200 Subject: [PATCH 3/7] WL4189 Add Handles.pm and use it from My::File::Path to show open handles. Rewrite rmtree to use File::Find so we can get better debug printouts when something fails --- mysql-test/lib/My/File/Path.pm | 43 ++++++++++++--------- mysql-test/lib/My/Handles.pm | 69 ++++++++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+), 18 deletions(-) create mode 100755 mysql-test/lib/My/Handles.pm diff --git a/mysql-test/lib/My/File/Path.pm b/mysql-test/lib/My/File/Path.pm index b6056bf470f..4ec7fbac33d 100644 --- a/mysql-test/lib/My/File/Path.pm +++ b/mysql-test/lib/My/File/Path.pm @@ -20,33 +20,40 @@ use Exporter; use base "Exporter"; our @EXPORT= qw / rmtree mkpath copytree /; - use File::Find; -use File::Path; use File::Copy; use Carp; - -no warnings 'redefine'; +use My::Handles; sub rmtree { my ($dir)= @_; - - # - # chmod all files to 0777 before calling rmtree - # find( { - no_chdir => 1, + bydepth => 1, + no_chdir => 1, wanted => sub { - chmod(0777, $_) - or warn("couldn't chmod(0777, $_): $!"); + my $name= $_; + if (!-l $name && -d _){ + return if (rmdir($name) == 1); + + chmod(0777, $name) or carp("couldn't chmod(0777, $name): $!"); + + return if (rmdir($name) == 1); + + # Failed to remove the directory, analyze + carp("Couldn't remove directory '$name': $!"); + My::Handles::show_handles($name); + } else { + return if (unlink($name) == 1); + + chmod(0777, $name) or carp("couldn't chmod(0777, $name): $!"); + + return if (unlink($name) == 1); + + carp("Couldn't delete file '$name': $!"); + My::Handles::show_handles($name); + } } - }, - $dir - ); - - - # Call rmtree from File::Path - goto &File::Path::rmtree; + }, $dir ); }; diff --git a/mysql-test/lib/My/Handles.pm b/mysql-test/lib/My/Handles.pm new file mode 100755 index 00000000000..66ee22b403f --- /dev/null +++ b/mysql-test/lib/My/Handles.pm @@ -0,0 +1,69 @@ +# -*- cperl -*- +# Copyright (C) 2008 MySQL AB +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +package My::Handles; + + +use strict; +use Carp; + +use My::Platform; + +my $handle_exe; + + +if (IS_WINDOWS){ + # Check if handle.exe is available + # Pass switch to accept the EULA to avoid hanging + # if the program hasn't been run before. + my $list= `handle.exe -? -accepteula 2>&1`; + foreach my $line (split('\n', $list)) + { + $handle_exe= "$1.$2" + if ($line =~ /Handle v([0-9]*)\.([0-9]*)/); + } + if ($handle_exe){ + print "Found handle.exe version $handle_exe\n"; + } +} + + +sub show_handles +{ + my ($dir)= @_; + return unless $handle_exe; + return unless $dir; + + $dir= native_path($dir); + + # Get a list of open handles in a particular directory + my $list= `handle.exe "$dir" 2>&1` or return; + + foreach my $line (split('\n', $list)) + { + return if ($line =~ /No matching handles found/); + } + + print "\n"; + print "=" x 50, "\n"; + print "Open handles in '$dir':\n"; + print "$list\n"; + print "=" x 50, "\n\n"; + + return; +} + +1; From 160e13cb4c6ebecdc341bc2b712f523e2f1c6639 Mon Sep 17 00:00:00 2001 From: Magnus Svensson Date: Mon, 6 Oct 2008 19:52:26 +0200 Subject: [PATCH 4/7] WL#4189 Only kill process that hasn't yet finished at end of mtr.pl. Improve debug printout --- mysql-test/lib/My/SafeProcess.pm | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/mysql-test/lib/My/SafeProcess.pm b/mysql-test/lib/My/SafeProcess.pm index 83749514622..f990d889a02 100644 --- a/mysql-test/lib/My/SafeProcess.pm +++ b/mysql-test/lib/My/SafeProcess.pm @@ -66,7 +66,9 @@ END { for my $proc (values %running){ if ( $proc->is_child($$) ){ #print "Killing: $proc\n"; - $proc->kill(); + if ($proc->wait_one(0)){ + $proc->kill(); + } } } } @@ -315,7 +317,7 @@ sub start_kill { $ret= system($safe_kill, $pid) >> 8; if (IS_CYGWIN and $ret == 3) { - print "safe_process is gone, kickstart the fake process\n"; + print "safe_process is gone, kickstart the fake process, $self\n"; if (kill(15, $self->{SAFE_PID}) != 1){ print STDERR "Failed to kickstart the fake process\n"; } From fc6a7def0b37c8f2b1298c3dc761dd8c9e09ebf0 Mon Sep 17 00:00:00 2001 From: Magnus Svensson Date: Wed, 8 Oct 2008 22:02:32 +0200 Subject: [PATCH 5/7] WL#4189 NO need to retry OpenEvent if the process does not exist anymore --- mysql-test/lib/My/SafeProcess/safe_kill_win.cc | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/mysql-test/lib/My/SafeProcess/safe_kill_win.cc b/mysql-test/lib/My/SafeProcess/safe_kill_win.cc index 9955a9f72f2..c6256fd92e1 100755 --- a/mysql-test/lib/My/SafeProcess/safe_kill_win.cc +++ b/mysql-test/lib/My/SafeProcess/safe_kill_win.cc @@ -49,12 +49,25 @@ int main(int argc, const char** argv ) while ((shutdown_event= OpenEvent(EVENT_MODIFY_STATE, FALSE, safe_process_name)) == NULL) { + /* + Check if the process is alive, otherwise there is really + no idea to retry the open of the event + */ + HANDLE process; + if ((process= OpenProcess(SYNCHRONIZE, FALSE, pid)) == NULL) + { + fprintf(stderr, "Could not open event or process %d, error: %d\n", + pid, GetLastError()); + exit(3); + } + CloseHandle(process); + if (retry_open_event--) Sleep(100); else { fprintf(stderr, "Failed to open shutdown_event '%s', error: %d\n", - safe_process_name, GetLastError()); + safe_process_name, GetLastError()); exit(3); } } From 2d2387927af4a369bc5982ea1cf23401b358adc0 Mon Sep 17 00:00:00 2001 From: Magnus Svensson Date: Wed, 8 Oct 2008 22:06:10 +0200 Subject: [PATCH 6/7] BUG#38559 Annoying cygwin problem fixed by resolving pid->winpid before kill instead of just after fork --- mysql-test/lib/My/SafeProcess.pm | 42 ++++++++++++++++++--------- mysql-test/lib/My/SafeProcess/Base.pm | 28 ++---------------- 2 files changed, 30 insertions(+), 40 deletions(-) diff --git a/mysql-test/lib/My/SafeProcess.pm b/mysql-test/lib/My/SafeProcess.pm index f990d889a02..655960222e7 100644 --- a/mysql-test/lib/My/SafeProcess.pm +++ b/mysql-test/lib/My/SafeProcess.pm @@ -148,7 +148,7 @@ sub new { print "### safe_path: ", $safe_path, " ", join(" ", @safe_args), "\n" if $verbose > 1; - my ($pid, $winpid)= create_process( + my $pid= create_process( path => $safe_path, input => $input, output => $output, @@ -161,7 +161,7 @@ sub new { my $proc= bless ({ SAFE_PID => $pid, - SAFE_WINPID => $winpid, + SAFE_WINPID => $pid, # Inidicates this is always a real process SAFE_NAME => $name, SAFE_SHUTDOWN => $shutdown, PARENT => $$, @@ -296,6 +296,18 @@ sub shutdown { } +sub _winpid ($) { + my ($pid)= @_; + + # In win32 perl, the pid is already the winpid + return $pid unless IS_CYGWIN; + + # In cygwin, the pid is the pseudo process -> + # get the real winpid of my_safe_process + return Cygwin::pid_to_winpid($pid); +} + + # # Tell the process to die as fast as possible # @@ -305,22 +317,24 @@ sub start_kill { _verbose("start_kill: $self"); my $ret= 1; - my $pid; + my $pid= $self->{SAFE_PID}; + die "INTERNAL ERROR: no pid" unless defined $pid; + if (IS_WINDOWS and defined $self->{SAFE_WINPID}) { die "INTERNAL ERROR: no safe_kill" unless defined $safe_kill; - die "INTERNAL ERROR: no winpid" unless defined $self->{SAFE_WINPID}; - # Use my_safe_kill to tell my_safe_process - # it's time to kill it's child and return - $pid= $self->{SAFE_WINPID}; - $ret= system($safe_kill, $pid) >> 8; - if (IS_CYGWIN and $ret == 3) - { - print "safe_process is gone, kickstart the fake process, $self\n"; - if (kill(15, $self->{SAFE_PID}) != 1){ - print STDERR "Failed to kickstart the fake process\n"; - } + my $winpid= _winpid($pid); + $ret= system($safe_kill, $winpid) >> 8; + + if ($ret == 3){ + print "Couldn't open the winpid: $winpid ", + "for pid: $pid, try one more time\n"; + sleep(1); + $winpid= _winpid($pid); + $ret= system($safe_kill, $winpid) >> 8; + print "Couldn't open the winpid: $winpid ", + "for pid: $pid, continue and see what happens...\n"; } } else diff --git a/mysql-test/lib/My/SafeProcess/Base.pm b/mysql-test/lib/My/SafeProcess/Base.pm index 2f3cf9d037a..3fc1b1be017 100644 --- a/mysql-test/lib/My/SafeProcess/Base.pm +++ b/mysql-test/lib/My/SafeProcess/Base.pm @@ -33,30 +33,6 @@ use base qw(Exporter); our @EXPORT= qw(create_process); -sub winpid { - my ($pid)= @_; - - return undef unless $^O eq "cygwin"; - - # The child get a new winpid when the exec takes - # place, wait for that to happen - my $winpid; - my $delay= 0; - do - { - # Yield to the child - select(undef, undef, undef, $delay); - # Increase the delay slightly for each loop - $delay += 0.000001; - - $winpid= Cygwin::pid_to_winpid($pid); - - } until ($winpid != $pid); - - return $winpid; -} - - # # safe_fork @@ -179,7 +155,7 @@ sub create_process { or croak("unable to reestablish STDIN"); #printf STDERR "stdin %d, stdout %d, stderr %d\n", # fileno STDIN, fileno STDOUT, fileno STDERR; - return wantarray ? ($pid, $pid) : $pid; + return $pid; } @@ -190,7 +166,7 @@ sub create_process { # Parent $pipe->reader(); my $line= <$pipe>; # Wait for child to say it's ready - return wantarray ? ($pid, winpid($pid)) : $pid; + return $pid; } $SIG{INT}= 'DEFAULT'; From 911e6386b9bca6aaaa49f56925be45d54679d12f Mon Sep 17 00:00:00 2001 From: Magnus Svensson Date: Wed, 8 Oct 2008 22:29:15 +0200 Subject: [PATCH 7/7] WL#4189 Add smoke target --- Makefile.am | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Makefile.am b/Makefile.am index d7745d96e6c..a623c79c177 100644 --- a/Makefile.am +++ b/Makefile.am @@ -119,6 +119,10 @@ test-reprepare: test: test-unit test-ns test-pr +smoke: + cd mysql-test ; \ + @PERL@ ./mysql-test-run.pl --do-test=s + test-full: test test-nr test-ps test-force: