Initialize all fields of Static{Result|Exception}WaitHandle

We force users to use the create() methods of StaticResultWaitHandle and StaticExceptionWaitHandle, which properly set m_resultOrException. However, deserialization will use the normal constructor which was failing to initialize the field. The destructor, then, would operate on random data. This broke hphpd when a stack trace had one of these objects on it somewhere. The 'where' command would succeed, but the next command (which deletes the stack trace), would segfault in the wait handle's destructor.

I think it's fair to not serialize this member. It's not exposed thru PHP except via joining with the wait handle, and I think an argument can be made that it's just plain wrong to join with a deserialized copy of a wait handle. So I've just initialized it to a reasonable default.
Esse commit está contido em:
Mike Magruder
2013-07-02 18:19:52 -07:00
commit de Sara Golemon
commit f4bed8899a
4 arquivos alterados com 40 adições e 2 exclusões
@@ -31,7 +31,7 @@ c_StaticExceptionWaitHandle::c_StaticExceptionWaitHandle(Class* cb)
}
c_StaticExceptionWaitHandle::~c_StaticExceptionWaitHandle() {
tvDecRefObj(&m_resultOrException);
tvRefcountedDecRefCell(&m_resultOrException);
}
void c_StaticExceptionWaitHandle::t___construct() {
+1 -1
Ver Arquivo
@@ -23,7 +23,7 @@ namespace HPHP {
///////////////////////////////////////////////////////////////////////////////
c_WaitHandle::c_WaitHandle(Class* cb)
: ExtObjectData(cb) {
: ExtObjectData(cb), m_resultOrException(make_tv<KindOfNull>()) {
}
c_WaitHandle::~c_WaitHandle() {
+34
Ver Arquivo
@@ -0,0 +1,34 @@
<?hh
// Copyright 2004-present Facebook. All Rights Reserved.
function main() {
// Make new wait handles with valid values.
$srwh = StaticResultWaitHandle::create(42);
$r = $srwh->join();
var_dump($r); // Shows 42 correctly.
$sewh = StaticExceptionWaitHandle::create(new Exception("Hi!"));
try {
$r = $sewh->join();
} catch (Exception $e) {
var_dump($e->getMessage()); // Shows "Hi!" correctly.
}
// Serialize the handles and let them go.
$s1 = serialize($srwh);
$s2 = serialize($sewh);
var_dump($s1);
var_dump($s2);
$srwh = null;
$erwh = null;
// Deserialize the handles in the reverse order, so they lay over
// each other's memory. We want to confirm that all fields are
// initialized correctly and that the destructor does not segfault.
$sewh = unserialize($s2);
$sewh = null; // Let it go
$srwh = unserialize($s1);
$srwh = null; // Let it go
}
main();
@@ -0,0 +1,4 @@
int(42)
string(3) "Hi!"
string(34) "O:22:"StaticResultWaitHandle":0:{}"
string(37) "O:25:"StaticExceptionWaitHandle":0:{}"