diff options
Diffstat (limited to 'mysql-test/lib')
-rw-r--r-- | mysql-test/lib/My/CoreDump.pm | 39 | ||||
-rw-r--r-- | mysql-test/lib/My/Platform.pm | 2 | ||||
-rw-r--r-- | mysql-test/lib/My/SafeProcess/safe_kill_win.cc | 23 | ||||
-rw-r--r-- | mysql-test/lib/My/SafeProcess/safe_process.cc | 50 | ||||
-rw-r--r-- | mysql-test/lib/My/SafeProcess/safe_process_win.cc | 10 | ||||
-rw-r--r-- | mysql-test/lib/mtr_cases.pm | 13 | ||||
-rw-r--r-- | mysql-test/lib/mtr_report.pm | 2 |
7 files changed, 116 insertions, 23 deletions
diff --git a/mysql-test/lib/My/CoreDump.pm b/mysql-test/lib/My/CoreDump.pm index 1ba94223b68..ae30f4f6074 100644 --- a/mysql-test/lib/My/CoreDump.pm +++ b/mysql-test/lib/My/CoreDump.pm @@ -264,6 +264,44 @@ EOF } +sub _lldb +{ + my ($core_name)= @_; + + print "\nTrying 'lldb' to get a backtrace from coredump $core_name\n"; + + # Create tempfile containing lldb commands + my ($tmp, $tmp_name)= tempfile(); + print $tmp + "bt\n", + "thread backtrace all\n", + "quit\n"; + close $tmp or die "Error closing $tmp_name: $!"; + + my $lldb_output= `lldb -c '$core_name' -s '$tmp_name' 2>&1`; + + unlink $tmp_name or die "Error removing $tmp_name: $!"; + + if ($? == 127) + { + print "lldb not found, cannot get the stack trace\n"; + return; + } + + return if $?; + return unless $lldb_output; + + resfile_print <<EOF . $lldb_output . "\n"; +Output from lldb follows. The first stack trace is from the failing thread. +The following stack traces are from all threads (so the failing one is +duplicated). +-------------------------- +EOF + return 1; +} + + + sub show { my ($class, $core_name, $exe_mysqld, $parallel)= @_; $hint_mysqld= $exe_mysqld; @@ -282,6 +320,7 @@ sub show { ( \&_dbx, \&_gdb, + \&_lldb, # TODO... ); diff --git a/mysql-test/lib/My/Platform.pm b/mysql-test/lib/My/Platform.pm index cb2ac3895e3..db1206f187e 100644 --- a/mysql-test/lib/My/Platform.pm +++ b/mysql-test/lib/My/Platform.pm @@ -112,6 +112,8 @@ sub check_socket_path_length { return 0 if ($^O eq 'aix'); # See Debian bug #670722 - failing on kFreeBSD even after setting short path return 0 if $^O eq 'gnukfreebsd' and length $path < 40; + # GNU/Hurd doesn't have hostpath(), but no limitation either + return 0 if $^O eq 'gnu'; require IO::Socket::UNIX; diff --git a/mysql-test/lib/My/SafeProcess/safe_kill_win.cc b/mysql-test/lib/My/SafeProcess/safe_kill_win.cc index bfd38928679..4a9d5f2b8cc 100644 --- a/mysql-test/lib/My/SafeProcess/safe_kill_win.cc +++ b/mysql-test/lib/My/SafeProcess/safe_kill_win.cc @@ -72,23 +72,24 @@ void dump_single_process(DWORD pid) char path[MAX_PATH]; char working_dir[MAX_PATH]; char tmpname[MAX_PATH]; + char *filename= 0; process= OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid); if (!process) { - fprintf(stderr, "safe_kill : cannot open process pid=%u to create dump, last error %u\n", + fprintf(stderr, "safe_kill : cannot open process pid=%lu to create dump, last error %lu\n", pid, GetLastError()); goto exit; } if (QueryFullProcessImageName(process, 0, path, &size) == 0) { - fprintf(stderr, "safe_kill : cannot read process path for pid %u, last error %u\n", + fprintf(stderr, "safe_kill : cannot read process path for pid %lu, last error %lu\n", pid, GetLastError()); goto exit; } - char *filename= strrchr(path, '\\'); + filename= strrchr(path, '\\'); if (filename) { filename++; @@ -115,17 +116,17 @@ void dump_single_process(DWORD pid) { if (!GetTempFileName(".", filename, 0, tmpname)) { - fprintf(stderr, "GetTempFileName failed, last error %u", GetLastError()); + fprintf(stderr, "GetTempFileName failed, last error %lu", GetLastError()); goto exit; } - strncat(tmpname, ".dmp", sizeof(tmpname)); + strncat_s(tmpname, ".dmp", sizeof(tmpname)); filename= tmpname; } if (!GetCurrentDirectory(MAX_PATH, working_dir)) { - fprintf(stderr, "GetCurrentDirectory failed, last error %u", GetLastError()); + fprintf(stderr, "GetCurrentDirectory failed, last error %lu", GetLastError()); goto exit; } @@ -134,14 +135,14 @@ void dump_single_process(DWORD pid) if (file == INVALID_HANDLE_VALUE) { - fprintf(stderr, "safe_kill : CreateFile() failed for file %s, working dir %s, last error = %u\n", + fprintf(stderr, "safe_kill : CreateFile() failed for file %s, working dir %s, last error = %lu\n", filename, working_dir, GetLastError()); goto exit; } if (!MiniDumpWriteDump(process, pid, file, MiniDumpNormal, 0, 0, 0)) { - fprintf(stderr, "Failed to write minidump to %s, working dir %s, last error %u\n", + fprintf(stderr, "Failed to write minidump to %s, working dir %s, last error %lu\n", filename, working_dir, GetLastError()); goto exit; } @@ -213,7 +214,7 @@ int main(int argc, const char** argv ) if (!GetExitCodeProcess(process,&exit_code)) { - fprintf(stderr, "GetExitCodeProcess failed, pid= %d, err= %d\n", + fprintf(stderr, "GetExitCodeProcess failed, pid= %lu, err= %lu\n", pid, GetLastError()); exit(1); } @@ -231,7 +232,7 @@ int main(int argc, const char** argv ) Sleep(100); else { - fprintf(stderr, "Failed to open shutdown_event '%s', error: %d\n", + fprintf(stderr, "Failed to open shutdown_event '%s', error: %lu\n", safe_process_name, GetLastError()); exit(3); } @@ -239,7 +240,7 @@ int main(int argc, const char** argv ) if(SetEvent(shutdown_event) == 0) { - fprintf(stderr, "Failed to signal shutdown_event '%s', error: %d\n", + fprintf(stderr, "Failed to signal shutdown_event '%s', error: %lu\n", safe_process_name, GetLastError()); CloseHandle(shutdown_event); exit(4); diff --git a/mysql-test/lib/My/SafeProcess/safe_process.cc b/mysql-test/lib/My/SafeProcess/safe_process.cc index 13d09198a0c..4d0d1e2a3a0 100644 --- a/mysql-test/lib/My/SafeProcess/safe_process.cc +++ b/mysql-test/lib/My/SafeProcess/safe_process.cc @@ -90,6 +90,53 @@ static void die(const char* fmt, ...) } +#ifdef __APPLE__ +#include <sys/sysctl.h> + + +/* + Eventually we may want to adopt kern.corefile parsing code from + https://opensource.apple.com/source/xnu/xnu-3247.1.106/bsd/kern/kern_proc.c +*/ + +void handle_core(pid_t pid) +{ + char corefile[256]; + int coredump; + size_t corefile_size= sizeof(corefile); + size_t coredump_size= sizeof(coredump); + + if (sysctlbyname("kern.coredump", &coredump, &coredump_size, 0, 0) || + sysctlbyname("kern.corefile", corefile, &corefile_size, 0, 0)) + { + message("sysctlbyname failed: %d (%s)", errno, strerror(errno)); + return; + } + + if (!coredump) + { + message("core dumps disabled, to enable run sudo sysctl kern.coredump=1"); + return; + } + + if (!strncmp(corefile, "/cores/core.%P", corefile_size)) + { + char from[256]; + char *to= from + 7; + + snprintf(from, sizeof(from), "/cores/core.%u", pid); + if (!access(from, R_OK)) + { + if (symlink(from, to)) + message("symlink failed: %d (%s)", errno, strerror(errno)); + } + } +} +#else +void handle_core(pid_t pid __attribute__((unused))) {} +#endif + + static int kill_child(bool was_killed) { int status= 0; @@ -113,7 +160,10 @@ static int kill_child(bool was_killed) } if (WIFSIGNALED(status)) + { message("Child killed by signal: %d", WTERMSIG(status)); + handle_core(child_pid); + } return exit_code; } diff --git a/mysql-test/lib/My/SafeProcess/safe_process_win.cc b/mysql-test/lib/My/SafeProcess/safe_process_win.cc index 4dd4e24f30d..8a5bb60a3f5 100644 --- a/mysql-test/lib/My/SafeProcess/safe_process_win.cc +++ b/mysql-test/lib/My/SafeProcess/safe_process_win.cc @@ -75,7 +75,7 @@ static void message(const char* fmt, ...) static void die(const char* fmt, ...) { - DWORD last_err= GetLastError(); + int last_err= GetLastError(); va_list args; fprintf(stderr, "%s: FATAL ERROR, ", safe_process_name); va_start(args, fmt); @@ -106,7 +106,7 @@ static void die(const char* fmt, ...) DWORD get_parent_pid(DWORD pid) { HANDLE snapshot; - DWORD parent_pid= -1; + DWORD parent_pid= 0; PROCESSENTRY32 pe32; pe32.dwSize= sizeof(PROCESSENTRY32); @@ -127,7 +127,7 @@ DWORD get_parent_pid(DWORD pid) } while(Process32Next( snapshot, &pe32)); CloseHandle(snapshot); - if (parent_pid == -1) + if (parent_pid == 0) die("Could not find parent pid"); return parent_pid; @@ -163,7 +163,7 @@ int main(int argc, const char** argv ) PROCESS_INFORMATION process_info= {0}; BOOL nocore= FALSE; - sprintf(safe_process_name, "safe_process[%d]", pid); + sprintf(safe_process_name, "safe_process[%lu]", pid); /* Create an event for the signal handler */ if ((shutdown_event= @@ -298,7 +298,7 @@ int main(int argc, const char** argv ) BOOL process_created= FALSE; BOOL jobobject_assigned= FALSE; - for (int i=0; i < sizeof(create_flags)/sizeof(create_flags[0]); i++) + for (size_t i=0; i < sizeof(create_flags)/sizeof(create_flags[0]); i++) { process_created= CreateProcess(NULL, (LPSTR)child_args, NULL, diff --git a/mysql-test/lib/mtr_cases.pm b/mysql-test/lib/mtr_cases.pm index 8c94c281edf..5958849da09 100644 --- a/mysql-test/lib/mtr_cases.pm +++ b/mysql-test/lib/mtr_cases.pm @@ -292,7 +292,7 @@ sub combinations_from_file($$) } else { return () if @::opt_combinations or not -f $filename; # Read combinations file in my.cnf format - mtr_verbose("Read combinations file"); + mtr_verbose("Read combinations file $filename"); my $config= My::Config->new($filename); foreach my $group ($config->option_groups()) { my $comb= { name => $group->name(), comb_opt => [] }; @@ -398,7 +398,7 @@ sub collect_suite_name($$) } } } else { - $suites{$suitename} = [ $::glob_mysql_test_dir, + $suites{$suitename} = [ $::glob_mysql_test_dir . "/main", my_find_dir(dirname($::glob_mysql_test_dir), [ @plugin_suitedirs ], 'main', NOT_REQUIRED) ]; @@ -470,7 +470,9 @@ sub process_suite { $suitename = $basename; } - my $suite = load_suite_object($suitename, $suitedir); + my $suite = load_suite_object($suitename, (($suitename eq "main") ? + $::glob_mysql_test_dir : + $suitedir)); # # Read suite config files, unless it was done aleady @@ -647,7 +649,7 @@ sub make_combinations($$@) { # Copy test options my $new_test= $test->copy(); - + # Prepend the combination options to master_opt and slave_opt # (on the command line combinations go *before* .opt files) unshift @{$new_test->{master_opt}}, @{$comb->{comb_opt}}; @@ -693,8 +695,6 @@ sub collect_one_test_case { my $tpath = shift; my $tname = shift; my %test_combs = map { $_ => 1 } @_; - - my $suitename = $suite->{name}; my $name = "$suitename.$tname"; my $filename = "$tpath/${tname}.test"; @@ -1096,6 +1096,7 @@ sub get_tags_from_file($$) { $file_to_slave_opts{$file}= $slave_opts; $file_combinations{$file}= [ ::uniq(@combinations) ]; $file_in_overlay{$file} = 1 if $in_overlay; + return @{$tags}; } diff --git a/mysql-test/lib/mtr_report.pm b/mysql-test/lib/mtr_report.pm index 0b99eafa4cf..25d3256ca4e 100644 --- a/mysql-test/lib/mtr_report.pm +++ b/mysql-test/lib/mtr_report.pm @@ -135,7 +135,7 @@ sub mtr_report_test ($) { my $logfile= $tinfo->{'logfile'}; my $warnings= $tinfo->{'warnings'}; my $result= $tinfo->{'result'}; - my $retry= $tinfo->{'retries'} ? "retry-" : ""; + my $retry= $tinfo->{'retries'} ? "retry-" : $tinfo->{'repeat'} ? "$tinfo->{'repeat'} " : ""; if ($result eq 'MTR_RES_FAILED'){ |