Valgrind Report for ext/mysqli/tests/mysqli_poll_kill.phpt ('int mysqli_poll() and kill')
Script
1:
<?php 2: require_once('connect.inc'); 3: 4: function get_connection() { 5: global $host, $user, $passwd, $db, $port, $socket; 6: 7: if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) 8: printf("[001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); 9: return $link; 10: } 11: 12: // Killing connection - 1 13: 14: $link = get_connection(); 15: if (true !== ($tmp = mysqli_query($link, "SELECT 1 AS 'processed before killed'", MYSQLI_ASYNC | MYSQLI_USE_RESULT))) 16: printf("[002] Expecting boolean/true got %s/%s\n", gettype($tmp), var_export($tmp, true)); 17: 18: // Sleep 0.1s - the asynchronous query should have been processed after the wait period 19: usleep(100000); 20: $thread_id = mysqli_thread_id($link); 21: mysqli_kill(get_connection(), $thread_id); 22: 23: $links = array($link); 24: $errors = array($link); 25: $reject = array($link); 26: 27: // Yes, 1 - the asynchronous query should have been processed 28: if (1 !== ($tmp = (mysqli_poll($links, $errors, $reject, 0, 10000)))) 29: printf("[003] Expecting int/1 got %s/%s\n", gettype($tmp), var_export($tmp, true)); 30: 31: if (!is_array($links) || empty($links)) 32: printf("[004] Expecting non-empty array got %s/%s\n", gettype($links), var_export($links, true)); 33: else 34: foreach ($links as $link) { 35: if (is_object($res = mysqli_reap_async_query($link))) { 36: // Yes, you can fetch a result - the query has been processed 37: var_dump(mysqli_fetch_assoc($res)); 38: mysqli_free_result($res); 39: } else if ($link->errno > 0) { 40: printf("[005] Error: %d\n", $link->errno); 41: } 42: } 43: 44: // No error! 45: if (!is_array($errors) || !empty($errors)) 46: printf("[006] Expecting non-empty array got %s/%s\n", gettype($errors), var_export($errors, true)); 47: 48: if (!is_array($reject) || !empty($reject)) 49: printf("[007] Expecting empty array got %s/%s\n", gettype($reject), var_export($reject, true)); 50: 51: // Lets pass a dead connection 52: $links = array($link); 53: $errors = array($link); 54: $reject = array($link); 55: if (0 !== ($tmp = mysqli_poll($links, $errors, $reject, 1))) 56: printf("[008] There should be no connection ready! Returned %s/%s, expecting int/0.\n", 57: gettype($tmp), var_export($tmp, true)); 58: 59: if (!empty($errors)) 60: printf("[009] There should be no errors but one rejected connection\n"); 61: 62: foreach ($reject as $mysqli) 63: if (mysqli_thread_id($mysqli) != $thread_id) { 64: printf("[010] Rejected thread %d should have rejected thread %d\n", 65: mysqli_thread_id($mysqli), $thread_id); 66: } 67: 68: // Killing connection - 2 69: 70: $link = get_connection(); 71: if (true !== ($tmp = mysqli_query($link, "SELECT 1", MYSQLI_ASYNC | MYSQLI_USE_RESULT))) 72: printf("[011] Expecting boolean/true got %s/%s\n", gettype($tmp), var_export($tmp, true)); 73: 74: usleep(100000); 75: $thread_id = mysqli_thread_id($link); 76: mysqli_kill(get_connection(), $thread_id); 77: 78: // Yes, 1 - fetch OK packet of kill! 79: $processed = 0; 80: do { 81: $links = array($link, $link); 82: $errors = array($link, $link); 83: $reject = array($link, $link); 84: $ready = mysqli_poll($links, $errors, $reject, 1); 85: 86: if (!empty($errors)) { 87: foreach ($errors as $mysqli) { 88: printf("[012] Error on thread %d: %s/%s\n", 89: mysqli_thread_id($mysqli), 90: mysqli_errno($mysqli), 91: mysqli_error($mysqli)); 92: } 93: break; 94: } 95: 96: if (!empty($reject)) { 97: foreach ($reject as $mysqli) { 98: printf("[013] Rejecting thread %d: %s/%s\n", 99: mysqli_thread_id($mysqli), 100: mysqli_errno($mysqli), 101: mysqli_error($mysqli)); 102: } 103: $processed += count($reject); 104: } 105: 106: foreach ($links as $mysqli) { 107: if (is_object($res = mysqli_reap_async_query($mysqli))) { 108: printf("Fetching from thread %d...\n", mysqli_thread_id($mysqli)); 109: var_dump(mysqli_fetch_assoc($res)); 110: } else if (mysqli_errno($mysqli) > 0) { 111: printf("[014] %d/%s\n", mysqli_errno($mysqli), mysqli_error($mysqli)); 112: } 113: $processed++; 114: } 115: 116: } while ($processed < 2); 117: 118: 119: // Killing connection - 3 120: 121: $link = get_connection(); 122: $thread_id = mysqli_thread_id($link); 123: mysqli_kill(get_connection(), $thread_id); 124: // Sleep 0.1s to ensure the KILL gets recognized 125: usleep(100000); 126: if (false !== ($tmp = mysqli_query($link, "SELECT 1 AS 'processed before killed'", MYSQLI_ASYNC | MYSQLI_USE_RESULT))) 127: printf("[015] Expecting boolean/false got %s/%s\n", gettype($tmp), var_export($tmp, true)); 128: 129: $links = array($link); 130: $errors = array($link); 131: $reject = array($link); 132: 133: if (0 !== ($tmp = (mysqli_poll($links, $errors, $reject, 0, 10000)))) 134: printf("[016] Expecting int/0 got %s/%s\n", gettype($tmp), var_export($tmp, true)); 135: 136: if (!is_array($links) || empty($links)) 137: printf("[017] Expecting non-empty array got %s/%s\n", gettype($links), var_export($links, true)); 138: else 139: foreach ($links as $link) { 140: if (is_object($res = mysqli_reap_async_query($link))) { 141: // No, you cannot fetch the result 142: var_dump(mysqli_fetch_assoc($res)); 143: mysqli_free_result($res); 144: } else if ($link->errno > 0) { 145: // But you are supposed to handle the error the way its shown here! 146: printf("[018] Error: %d/%s\n", $link->errno, $link->error); 147: } 148: } 149: 150: // None of these will indicate an error, check errno on the list of returned connections! 151: if (!is_array($errors) || !empty($errors)) 152: printf("[019] Expecting non-empty array got %s/%s\n", gettype($errors), var_export($errors, true)); 153: 154: if (!is_array($reject) || !empty($reject)) 155: printf("[020] Expecting empty array got %s/%s\n", gettype($reject), var_export($reject, true)); 156: 157: 158: mysqli_close($link); 159: print "done!"; 160: ?> 161:
Report
==8914== Invalid read of size 8
==8914== at 0xD60050: _php_stream_cast (cast.c:298)
==8914== by 0xCCBECC: mysqlnd_stream_array_to_fd_set (mysqlnd.c:1274)
==8914== by 0xCCC418: _mysqlnd_poll (mysqlnd.c:1358)
==8914== by 0x8FFBF2: zif_mysqli_poll (mysqli_nonapi.c:800)
==8914== by 0xE70D6B: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:543)
==8914== by 0xE7AD7B: ZEND_DO_FCALL_SPEC_CONST_HANDLER (zend_vm_execute.h:2322)
==8914== by 0xE6E9A8: execute_ex (zend_vm_execute.h:356)
==8914== by 0xE6F53A: zend_execute (zend_vm_execute.h:381)
==8914== by 0xE0CA32: zend_execute_scripts (zend.c:1316)
==8914== by 0xD3043F: php_execute_script (main.c:2479)
==8914== by 0xFF1374: do_cli (php_cli.c:993)
==8914== by 0xFF2B21: main (php_cli.c:1377)
==8914== Address 0x10 is not stack'd, malloc'd or (recently) free'd
==8914==
==8914==
==8914== Process terminating with default action of signal 11 (SIGSEGV)
==8914== Access not within mapped region at address 0x10
==8914== at 0xD60050: _php_stream_cast (cast.c:298)
==8914== by 0xCCBECC: mysqlnd_stream_array_to_fd_set (mysqlnd.c:1274)
==8914== by 0xCCC418: _mysqlnd_poll (mysqlnd.c:1358)
==8914== by 0x8FFBF2: zif_mysqli_poll (mysqli_nonapi.c:800)
==8914== by 0xE70D6B: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:543)
==8914== by 0xE7AD7B: ZEND_DO_FCALL_SPEC_CONST_HANDLER (zend_vm_execute.h:2322)
==8914== by 0xE6E9A8: execute_ex (zend_vm_execute.h:356)
==8914== by 0xE6F53A: zend_execute (zend_vm_execute.h:381)
==8914== by 0xE0CA32: zend_execute_scripts (zend.c:1316)
==8914== by 0xD3043F: php_execute_script (main.c:2479)
==8914== by 0xFF1374: do_cli (php_cli.c:993)
==8914== by 0xFF2B21: main (php_cli.c:1377)
==8914== If you believe this happened as a result of a stack
==8914== overflow in your program's main thread (unlikely but
==8914== possible), you can try to increase the size of the
==8914== main thread stack using the --main-stacksize= flag.
==8914== The main thread stack size used in this run was 33554432.
Generated at Wed, 15 May 2013 22:03:26 +0000 (7 days ago)
|