From: rich at kastle dot com Operating system: Windows NT 4.0 SP6 PHP version: 4.3.2RC1 PHP Bug Type: COM related Bug description: COM functions which raise exceptions are invoked twice
If php_COM_invoke receives an error as a result of trying to invoke a COM method via C_TYPEINFO_VT(obj)->Invoke, it assumes that the dispatch failed and tries again using C_DISPATCH_VT(obj)->Invoke. However, if the first Invoke succeeds (i.e. actually call into the object method) but the method raises a COM exception, it returns DISP_E_EXCEPTION. php_COM_invoke will then call the same method again using C_DISPATCH_VT. (In my particular case, the COM method was performing some subsequent phases of a larger DB transaction, encountered a deadlock, then rolled back the DB transaction and reported the event by raising an exception. php_COM_invoke swallowed the exception without report and invoked the method again, which, this time, did not encounter the same deadlock, leaving my code without knowledge that a deadlock had caused some of my DB updates to be rolled back. It took me four days to figure out what in the world was happening.) Here's a diff against COM.c which checks for DISP_E_EXCEPTION as a special case. (This diff is against 4.3.2RC1 but AFAICS this error has existed all along.) diff -r temp/php-4.3.2RC1\ext\com\COM.c php-4.3.2RC1\ext\com\COM.c 128,129c128,130 < hr = C_DISPATCH_VT(obj)->Invoke(C_DISPATCH(obj), dispIdMember, &IID_NULL, LOCALE_SYSTEM_DEFAULT, wFlags, pDispParams, pVarResult, &ExceptInfo, &ArgErr); < if (SUCCEEDED(hr)) { --- > if(hr != DISP_E_EXCEPTION) { > hr = > C_DISPATCH_VT(obj)->Invoke(C_DISPATCH(obj), dispIdMember, &IID_NULL, LOCALE_SYSTEM_DEFAULT, wFlags, pDispParams, pVarResult, &ExceptInfo, &ArgErr); > if (SUCCEEDED(hr)) { 131,137c132,139 < * ITypLib doesn't work < * Release ITypeLib and fall back to IDispatch < */ < < C_TYPEINFO_VT(obj)->Release(C_TYPEINFO(obj)); < C_HASTLIB(obj) = FALSE; < C_TYPEINFO(obj) = NULL; --- > * ITypLib doesn't work > * Release ITypeLib and fall back to IDispatch > */ > > > C_TYPEINFO_VT(obj)->Release(C_TYPEINFO(obj)); > C_HASTLIB(obj) = FALSE; > C_TYPEINFO(obj) = NULL; > } -- Edit bug report at http://bugs.php.net/?id=22899&edit=1 -- Try a CVS snapshot: http://bugs.php.net/fix.php?id=22899&r=trysnapshot Fixed in CVS: http://bugs.php.net/fix.php?id=22899&r=fixedcvs Fixed in release: http://bugs.php.net/fix.php?id=22899&r=alreadyfixed Need backtrace: http://bugs.php.net/fix.php?id=22899&r=needtrace Try newer version: http://bugs.php.net/fix.php?id=22899&r=oldversion Not developer issue: http://bugs.php.net/fix.php?id=22899&r=support Expected behavior: http://bugs.php.net/fix.php?id=22899&r=notwrong Not enough info: http://bugs.php.net/fix.php?id=22899&r=notenoughinfo Submitted twice: http://bugs.php.net/fix.php?id=22899&r=submittedtwice register_globals: http://bugs.php.net/fix.php?id=22899&r=globals PHP 3 support discontinued: http://bugs.php.net/fix.php?id=22899&r=php3 Daylight Savings: http://bugs.php.net/fix.php?id=22899&r=dst IIS Stability: http://bugs.php.net/fix.php?id=22899&r=isapi Install GNU Sed: http://bugs.php.net/fix.php?id=22899&r=gnused