summaryrefslogtreecommitdiff
path: root/mysql-test/lib
diff options
context:
space:
mode:
authorBjorn Munch <Bjorn.Munch@sun.com>2009-03-18 13:44:05 +0100
committerBjorn Munch <Bjorn.Munch@sun.com>2009-03-18 13:44:05 +0100
commit1b922ca6e8b9766d55c93d9a4284d960d1866ca8 (patch)
tree22fa564be98b9e6ba9a43259eb803e793e6cf1e6 /mysql-test/lib
parent6f7f233b6cbaa248e08a4eef7e75dc4aaa9d1fe4 (diff)
parent3ed5a61f2972880e73b55ced79a75fc346b5ab35 (diff)
downloadmariadb-git-1b922ca6e8b9766d55c93d9a4284d960d1866ca8.tar.gz
merge from main
Diffstat (limited to 'mysql-test/lib')
-rw-r--r--mysql-test/lib/My/CoreDump.pm127
-rwxr-xr-xmysql-test/lib/My/SafeProcess/safe_process_win.cc19
-rw-r--r--mysql-test/lib/mtr_gcov.pl58
3 files changed, 176 insertions, 28 deletions
diff --git a/mysql-test/lib/My/CoreDump.pm b/mysql-test/lib/My/CoreDump.pm
index 599f9ccbfca..f3e9f521384 100644
--- a/mysql-test/lib/My/CoreDump.pm
+++ b/mysql-test/lib/My/CoreDump.pm
@@ -104,9 +104,136 @@ EOF
}
+# Check that Debugging tools for Windows are installed
+sub cdb_check {
+ `cdb -? 2>&1`;
+ if ($? >> 8)
+ {
+ print "Cannot find cdb. Please Install Debugging tools for Windows\n";
+ print "from http://www.microsoft.com/whdc/devtools/debugging/";
+ if($ENV{'ProgramW6432'})
+ {
+ print "install64bit.mspx (native x64 version)\n";
+ }
+ else
+ {
+ print "installx86.mspx\n";
+ }
+ }
+}
+
+
+sub _cdb {
+ my ($core_name)= @_;
+ print "\nTrying 'cdb' to get a backtrace\n";
+ return unless -f $core_name;
+
+ # Try to set environment for debugging tools for Windows
+ if ($ENV{'PATH'} !~ /Debugging Tools/)
+ {
+ if ($ENV{'ProgramW6432'})
+ {
+ # On x64 computer
+ $ENV{'PATH'}.= ";".$ENV{'ProgramW6432'}."\\Debugging Tools For Windows (x64)";
+ }
+ else
+ {
+ # On x86 computer. Newest versions of Debugging tools are installed in the
+ # directory with (x86) suffix, older versions did not have this suffix.
+ $ENV{'PATH'}.= ";".$ENV{'ProgramFiles'}."\\Debugging Tools For Windows (x86)";
+ $ENV{'PATH'}.= ";".$ENV{'ProgramFiles'}."\\Debugging Tools For Windows";
+ }
+ }
+
+
+ # Read module list, find out the name of executable and
+ # build symbol path (required by cdb if executable was built on
+ # different machine)
+ my $tmp_name= $core_name.".cdb_lmv";
+ `cdb -z $core_name -c \"lmv;q\" > $tmp_name 2>&1`;
+ if ($? >> 8)
+ {
+ unlink($tmp_name);
+ # check if cdb is installed and complain if not
+ cdb_check();
+ return;
+ }
+
+ open(temp,"< $tmp_name");
+ my %dirhash=();
+ while(<temp>)
+ {
+ if($_ =~ /Image path\: (.*)/)
+ {
+ if (rindex($1,'\\') != -1)
+ {
+ my $dir= substr($1, 0, rindex($1,'\\'));
+ $dirhash{$dir}++;
+ }
+ }
+ }
+ close(temp);
+ unlink($tmp_name);
+
+ my $image_path= join(";", (keys %dirhash),".");
+
+ # For better callstacks, setup _NT_SYMBOL_PATH to include
+ # OS symbols. Note : Dowloading symbols for the first time
+ # can take some minutes
+ if (!$ENV{'_NT_SYMBOL_PATH'})
+ {
+ my $windir= $ENV{'windir'};
+ my $symbol_cache= substr($windir ,0, index($windir,'\\'))."\\cdb_symbols";
+
+ print "OS debug symbols will be downloaded and stored in $symbol_cache.\n";
+ print "You can control the location of symbol cache with _NT_SYMBOL_PATH\n";
+ print "environment variable. Please refer to Microsoft KB article\n";
+ print "http://support.microsoft.com/kb/311503 for details about _NT_SYMBOL_PATH\n";
+ print "-------------------------------------------------------------------------\n";
+
+ $ENV{'_NT_SYMBOL_PATH'}.=
+ "srv*".$symbol_cache."*http://msdl.microsoft.com/download/symbols";
+ }
+
+ my $symbol_path= $image_path.";".$ENV{'_NT_SYMBOL_PATH'};
+
+
+ # Run cdb. Use "analyze" extension to print crashing thread stacktrace
+ # and "uniqstack" to print other threads
+
+ my $cdb_cmd = "!sym prompts off; !analyze -v; .ecxr; !for_each_frame dv /t;!uniqstack -p;q";
+ my $cdb_output=
+ `cdb -z $core_name -i "$image_path" -y "$symbol_path" -t 0 -lines -c "$cdb_cmd" 2>&1`;
+ return if $? >> 8;
+ return unless $cdb_output;
+
+ # Remove comments (lines starting with *), stack pointer and frame
+ # pointer adresses and offsets to function to make output better readable
+ $cdb_output=~ s/^\*.*\n//gm;
+ $cdb_output=~ s/^([\:0-9a-fA-F\`]+ )+//gm;
+ $cdb_output=~ s/^ChildEBP RetAddr//gm;
+ $cdb_output=~ s/^Child\-SP RetAddr Call Site//gm;
+ $cdb_output=~ s/\+0x([0-9a-fA-F]+)//gm;
+
+ print <<EOF, $cdb_output, "\n";
+Output from cdb follows. Faulting thread is printed twice,with and without function parameters
+Search for STACK_TEXT to see the stack trace of
+the faulting thread. Callstacks of other threads are printed after it.
+EOF
+ return 1;
+}
+
+
sub show {
my ($class, $core_name)= @_;
+ # On Windows, rely on cdb to be there...
+ if (IS_WINDOWS)
+ {
+ _cdb($core_name);
+ return;
+ }
+
# We try dbx first; gdb itself may coredump if run on a Sun Studio
# compiled binary on Solaris.
diff --git a/mysql-test/lib/My/SafeProcess/safe_process_win.cc b/mysql-test/lib/My/SafeProcess/safe_process_win.cc
index 640254875c9..4fb89f098ed 100755
--- a/mysql-test/lib/My/SafeProcess/safe_process_win.cc
+++ b/mysql-test/lib/My/SafeProcess/safe_process_win.cc
@@ -77,14 +77,29 @@ static void message(const char* fmt, ...)
static void die(const char* fmt, ...)
{
+ DWORD last_err= GetLastError();
va_list args;
fprintf(stderr, "%s: FATAL ERROR, ", safe_process_name);
va_start(args, fmt);
vfprintf(stderr, fmt, args);
fprintf(stderr, "\n");
va_end(args);
- if (int last_err= GetLastError())
- fprintf(stderr, "error: %d, %s\n", last_err, strerror(last_err));
+ if (last_err)
+ {
+ char *message_text;
+ if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER
+ |FORMAT_MESSAGE_IGNORE_INSERTS, NULL, last_err , 0, (LPSTR)&message_text,
+ 0, NULL))
+ {
+ fprintf(stderr,"error: %d, %s\n",last_err, message_text);
+ LocalFree(message_text);
+ }
+ else
+ {
+ /* FormatMessage failed, print error code only */
+ fprintf(stderr,"error:%d\n", last_err);
+ }
+ }
fflush(stderr);
exit(1);
}
diff --git a/mysql-test/lib/mtr_gcov.pl b/mysql-test/lib/mtr_gcov.pl
index 5049fdd6063..f531889b08d 100644
--- a/mysql-test/lib/mtr_gcov.pl
+++ b/mysql-test/lib/mtr_gcov.pl
@@ -22,40 +22,46 @@ use strict;
sub gcov_prepare ($) {
my ($dir)= @_;
+ print "Purging gcov information from '$dir'...\n";
- `find $dir -name \*.gcov \
- -or -name \*.da | xargs rm`;
+ system("find $dir -name \*.gcov -o -name \*.da"
+ . " -o -name \*.gcda | grep -v 'README.gcov\$' | xargs rm");
}
-my @mysqld_src_dirs=
- (
- "strings",
- "mysys",
- "include",
- "extra",
- "regex",
- "isam",
- "merge",
- "myisam",
- "myisammrg",
- "heap",
- "sql",
- );
-
+#
+# Collect gcov statistics.
+# Arguments:
+# $dir basedir, normally source directory
+# $gcov gcov utility program [path] name
+# $gcov_msg message file name
+# $gcov_err error file name
+#
sub gcov_collect ($$$) {
my ($dir, $gcov, $gcov_msg, $gcov_err)= @_;
+ # Get current directory to return to later.
my $start_dir= cwd();
- print "Collecting source coverage info...\n";
- -f $gcov_msg and unlink($gcov_msg);
- -f $gcov_err and unlink($gcov_err);
- foreach my $d ( @mysqld_src_dirs )
- {
- chdir("$dir/$d");
- foreach my $f ( (glob("*.h"), glob("*.cc"), glob("*.c")) )
- {
- `$gcov $f 2>>$gcov_err >>$gcov_msg`;
+ print "Collecting source coverage info using '$gcov'...\n";
+ -f "$start_dir/$gcov_msg" and unlink("$start_dir/$gcov_msg");
+ -f "$start_dir/$gcov_err" and unlink("$start_dir/$gcov_err");
+
+ my @dirs= `find "$dir" -type d -print | sort`;
+ #print "List of directories:\n@dirs\n";
+
+ foreach my $d ( @dirs ) {
+ my $dir_reported= 0;
+ chomp($d);
+ chdir($d) or next;
+
+ foreach my $f ( (glob("*.h"), glob("*.cc"), glob("*.c")) ) {
+ $f =~ /(.*)\.[ch]c?/;
+ -f "$1.gcno" or next;
+ if (!$dir_reported) {
+ print "Collecting in '$d'...\n";
+ $dir_reported= 1;
+ }
+ system("$gcov $f 2>>$start_dir/$gcov_err >>$start_dir/$gcov_msg");
}
chdir($start_dir);
}