diff --git a/client/mysqltest.cc b/client/mysqltest.cc index 8efa667db4a0..d92d32d0825b 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -133,6 +133,7 @@ static char line_buffer[MAX_DELIMITER_LENGTH], *line_buffer_pos= line_buffer; static const char *opt_server_public_key= 0; #endif static my_bool can_handle_expired_passwords= TRUE; +static char closed_connection[]= "-closed_connection-"; /* Info on properties that can be set with --enable_X and --disable_X */ @@ -1665,7 +1666,8 @@ void close_connections() mysql_close(&next_con->mysql); if (next_con->util_mysql) mysql_close(next_con->util_mysql); - my_free(next_con->name); + if (strcmp(next_con->name, closed_connection)) + my_free(next_con->name); } my_free(connections); DBUG_VOID_RETURN; @@ -2438,6 +2440,7 @@ void check_require(DYNAMIC_STRING* ds, const char *fname) { char reason[FN_REFLEN]; fn_format(reason, fname, "", "", MY_REPLACE_EXT | MY_REPLACE_DIR); + dynstr_free(ds); abort_not_supported_test("Test requires: '%s'", reason); } DBUG_VOID_RETURN; @@ -3082,6 +3085,7 @@ void var_set_query_get_value(struct st_command *command, VAR *var) mysql_sqlstate(mysql), &ds_res); /* If error was acceptable, return empty string */ dynstr_free(&ds_query); + dynstr_free(&ds_col); eval_expr(var, "", 0); DBUG_VOID_RETURN; } @@ -5311,8 +5315,7 @@ void do_get_errcodes(struct st_command *command) /* code to handle variables passed to mysqltest */ if( *p == '$') { - const char* fin; - VAR *var = var_get(p,&fin,0,0); + VAR *var = var_get(p,NULL,0,0); p=var->str_val; end=p+var->str_val_len; } @@ -5591,6 +5594,8 @@ void do_close_connection(struct st_command *command) { vio_delete(con->mysql.net.vio); con->mysql.net.vio = 0; + net_end(&con->mysql.net); + free_old_query(&con->mysql); } } #else @@ -5618,8 +5623,8 @@ void do_close_connection(struct st_command *command) When the connection is closed set name to "-closed_connection-" to make it possible to reuse the connection name. */ - if (!(con->name = my_strdup("-closed_connection-", MYF(MY_WME)))) - die("Out of memory"); + con->name= closed_connection; + con->name_len= strlen(closed_connection); if (con == cur_con) { @@ -5828,6 +5833,7 @@ int connect_n_handle_errors(struct st_command *command, var_set_errno(mysql_errno(con)); handle_error(command, mysql_errno(con), mysql_error(con), mysql_sqlstate(con), ds); + mysql_close(con); return 0; /* Not connected */ } @@ -5988,7 +5994,7 @@ void do_connect(struct st_command *command) con_slot= next_con; else { - if (!(con_slot= find_connection_by_name("-closed_connection-"))) + if (!(con_slot= find_connection_by_name(closed_connection))) die("Connection limit exhausted, you can have max %d connections", opt_max_connections); } @@ -7852,10 +7858,12 @@ void run_query_normal(struct st_connection *cn, struct st_command *command, handle_error(command, mysql_errno(mysql), mysql_error(mysql), mysql_sqlstate(mysql), ds); + dynstr_free(&temp); goto end; } } dynstr_append_mem(ds, temp.str, temp.length); + dynstr_free(&temp); } else { @@ -7912,6 +7920,11 @@ void run_query_normal(struct st_connection *cn, struct st_command *command, revert_properties(); end: + if (res) + { + mysql_free_result_wrapper(res); + res= 0; + } cn->pending= FALSE; /* @@ -8584,14 +8597,22 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags) if (sp_created) { if (util_query(mysql, "DROP PROCEDURE mysqltest_tmp_sp ")) + { + if (ds == &ds_result) + dynstr_free(&ds_result); die("Failed to drop sp: %d: %s", mysql_errno(mysql), mysql_error(mysql)); + } } if (view_created) { if (util_query(mysql, "DROP VIEW mysqltest_tmp_v ")) + { + if (ds == &ds_result) + dynstr_free(&ds_result); die("Failed to drop view: %d: %s", - mysql_errno(mysql), mysql_error(mysql)); + mysql_errno(mysql), mysql_error(mysql)); + } } if (command->require_file[0]) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 545b8d0968df..0707b550ef32 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -459,6 +459,7 @@ sub main { # Create child processes my %children; + my %children_logdir; for my $child_num (1..$opt_parallel){ my $child_pid= My::SafeProcess::Base::_safe_fork(); if ($child_pid == 0){ @@ -476,6 +477,12 @@ sub main { exit(1); } + if ($opt_parallel > 1) { + $children_logdir{"$opt_vardir/$child_num/log/"}= 1; + } + else { + $children_logdir{"$opt_vardir/log/"}= 1; + } $children{$child_pid}= 1; } ####################################################################### @@ -540,12 +547,30 @@ sub main { $tinfo->{worker} = 0 if $opt_parallel > 1; if ($valgrind_reports) { $tinfo->{result}= 'MTR_RES_FAILED'; - $tinfo->{comment}= "Valgrind reported failures at shutdown, see above"; + $tinfo->{comment}= "Valgrind reported failures at shutdown"; $tinfo->{failures}= 1; + mtr_report_test($tinfo); + + foreach my $logdir (keys %children_logdir) { + opendir(LOGDIR, $logdir) + or mtr_error("Can't open log directory: $logdir"); + + while (my $file = readdir(LOGDIR)) { + next unless ($file =~ m/\.valgrind$/); + + open(FILE, "< $logdir/$file" ) or mtr_error("Can't open file: $file"); + while() { + print; + } + close FILE; + } + + closedir(LOGDIR); + } } else { $tinfo->{result}= 'MTR_RES_PASSED'; + mtr_report_test($tinfo); } - mtr_report_test($tinfo); push @$completed, $tinfo; } @@ -5399,7 +5424,7 @@ ($$) my $output= $mysqld->value('#log-error'); # Remember this log file for valgrind error report search - $mysqld_logs{$output}= 1 if $opt_valgrind; + $mysqld_logs{$output}= 1 if $opt_valgrind_mysqld; # Remember data dir for gmon.out files if using gprof $gprof_dirs{$mysqld->value('datadir')}= 1 if $opt_gprof; @@ -6080,6 +6105,8 @@ ($) mtr_init_args(\$args); valgrind_arguments($args, \$exe); mtr_add_arg($args, "%s", $_) for @args_saved; + # Remember this log file for valgrind error report search + $mysqld_logs{$path_testlog} = 1 } mtr_add_arg($args, "--test-file=%s", $tinfo->{'path'}); @@ -6427,10 +6454,14 @@ () my $found_report= 0; my $err_in_report= 0; my $ignore_report= 0; + my $valgrind_out= "$log_file.valgrind"; my $LOGF = IO::File->new($log_file) or mtr_error("Could not open file '$log_file' for reading: $!"); + my $OUTF = IO::File->new($valgrind_out, 'w') + or mtr_error("Could not open file '$valgrind_out' for writing$!"); + while ( my $line = <$LOGF> ) { if ($line =~ /^CURRENT_TEST: (.+)$/) @@ -6441,10 +6472,10 @@ () { if ($err_in_report) { - mtr_print ("Valgrind report from $log_file after tests:\n", - @culprits); - mtr_print_line(); - print ("$valgrind_rep\n"); + print $OUTF "Valgrind report from $log_file after tests:\n"; + print $OUTF join("\n", @culprits); + print $OUTF "\n\n"; + print $OUTF "$valgrind_rep\n"; $found_err= 1; $err_in_report= 0; } @@ -6456,10 +6487,20 @@ () push (@culprits, $testname); next; } - # This line marks a report to be ignored - $ignore_report=1 if $line =~ /VALGRIND_DO_QUICK_LEAK_CHECK/; - # This line marks the start of a valgrind report - $found_report= 1 if $line =~ /^==\d+== .* SUMMARY:/; + + # The mysqltest log is handled differently from the mysqld logs because + # we check the mysqld logs for valgrind errors after every run. This is + # why we only look at the summary for mysqld. For mysqltest, we need to + # look at all valgrind errors that may have occurred. + if ($log_file eq $path_testlog) { + $found_report= 1 if $line =~ /^==\d+==/; + } + else { + # This line marks a report to be ignored + $ignore_report=1 if $line =~ /VALGRIND_DO_QUICK_LEAK_CHECK/; + # This line marks the start of a valgrind report + $found_report= 1 if $line =~ /^==\d+== .* SUMMARY:/; + } if ($ignore_report && $found_report) { $ignore_report= 0; @@ -6479,11 +6520,14 @@ () $LOGF= undef; if ($err_in_report) { - mtr_print ("Valgrind report from $log_file after tests:\n", @culprits); - mtr_print_line(); - print ("$valgrind_rep\n"); + print $OUTF "Valgrind report from $log_file after tests:\n"; + print $OUTF join("\n", @culprits); + print $OUTF "\n\n"; + print $OUTF "$valgrind_rep\n"; $found_err= 1; } + + $OUTF= undef; } return $found_err;