Last active
December 20, 2015 08:29
-
-
Save Aatch/6100515 to your computer and use it in GitHub Desktop.
Memory Corruption
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/* | |
Horrible Memory Corruption Bug. | |
So using PHPUnit, the file below (more-or-less) gets included inside a function as bootstrapping | |
script for PHPUnit. The first time it runs (i.e. no bytecode cache) it works fine. The second | |
causes a segfault in release mode. It asserts if assertions are turned on (-DALWAYS_ASSERT). | |
The assertion is: | |
'hphp/runtime/vm/jit/translator.cpp:4044: HPHP::Transl::{anonymous}::DeferredPathInvalidate::DeferredPathInvalidate(const string&): Assertion `m_path.size() >= 1 && m_path[0] == '/'' failed.' | |
Some printf-debugging led me to find that the path that is asserting, has a size of | |
7668058320836127338 and starts with 'jjjjjjjjmes/...', which is the smart-allocator's poision pattern | |
it puts in (0x6a6a6a6a6a6a6a6a) when it frees things. The path in question is actually the path to the | |
offending file. | |
*/ | |
// boostrap.php | |
$connectString = sprintf('host=\'%s\' user=\'%s\' password=\'%s\' dbname=postgres', DATABASE_HOST, DATABASE_USER, DATABASE_PASS); | |
$con = pg_connect($connectString) or die('Unable to connect to postgres'); | |
$dbname = 'PR_test_' . str_replace('.', '_', microtime(true)); | |
pg_query($con, 'CREATE DATABASE '.pg_escape_identifier($con, $dbname)) or die('Unable to create database'); | |
/* | |
Another wierd part, if the result of that query is assigned to a variable, then the assertion goes away. | |
Other things that can trigger the error are: calling `unset` on the result resource or wrapping it all in a | |
function and calling that function. It seems that the corruption only occurs if the resource is cleaned up | |
by the destructor instead of the sweeper. | |
The final odd part is that directly running any variation of the above works fine, it only seems to be when | |
done via the PHPUnit test harness. | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Some extra notes: I thought it might be something related to stack-smashing so I built with
-fstack-protector-all
, which didn't show anything.