Stephan Bergmann wrote:
It has always been made quite clear that calling cppu::getCaughtException will only work under tightly restricted circumstances (<http://udk.openoffice.org/source/browse/udk/cppuhelper/inc/cppuhelper/exc_hlp.hxx?rev=1.9&view=markup>). It appears that the combination of two recent changes (the switch to Microsoft .Net 2005/2008 compilers together with the Three-Layer Office) has killed this feature completely, however.

Debugging <http://www.openoffice.org/issues/show_bug.cgi?id=88671> (of which <http://www.openoffice.org/issues/show_bug.cgi?id=88460> is probably a duplicate) shows the following: On a Windows machine where the relevant compiler runtime libraries are not installed system wide (msvcr90.dll in the case of the .Net 2008 compiler, OOo code wntmsci12), msvcr90.dll is loaded multiple times into the process (it has to be present in both the URE\bin and Basis 3.0\program directories; otherwise soffice would not even start), and an exception thrown at desktop/source/deployment/registry/dp_registry.cxx:1.12 l. 486 causes a crash when it is caught one stack frame up at desktop/source/deployment/registry/package/dp_package.cxx:1.26 l. 1187 and cppu::getCaughtException is called. This appears to be due to the fact that cppuhelper3MSC.dll and/or msci_uno.dll (implementing cppu::getCaughtException) are located in the URE\bin layer and use the instance of msvcr90.dll loaded from there while deploymentmi.uno.dll (implementing the desktop/source/deployment code) is located in the Basis 3.0\program layer and uses the other (identical) instance of msvcr90.dll loaded from there.

Further debugging makes the picture clearer: In general, information about a thrown C++ exception (in particular the RTTI, which the C++ UNO bridge is interested in) is contained in the Windows SEH (Structured Exception Handling) EXCEPTION_RECORD that is made available to SEH __except handlers (and the C++ UNO bridge indeed uses such an SEH __except handler to get at the wanted RTTI information, see bridges/source/cpp_uno/msvc_win32_intel/uno2cpp.cxx:1.14 l. 272 and bridges/source/cpp_uno/msvc_win32_intel/except.cxx:1.17 l. 509).

However, when the thrown exception is a re-thrown one, the EXCEPTION_RECORD contains null values, and the relevant exception information has to be picked up from a per-msvcr90.dll-instance TLS (Thread Local Storage) block (see bridges/source/cpp_uno/msvc_win32_intel/except.cxx:1.17 l. 519). Since the TLS block is per-msvcr90.dll-instance, and we have two such instances in the above scenario, the code in except.cxx looks in the wrong instance's block, and fails. (The C++ Runtime itself somehow appears to successfully manage scenarios where an exception is thrown and re-thrown in the context of one msvcr90.dll instance and caught in the context of another, but I was unable to see the magic that makes it work.)

And all this weird code in except.cxx is only necessary because our C++ UNO exceptions do not make plain C++ RTTI available (see Frank's post)! This got me thinking: What about actually changing the C++ UNO binding, conditionally for _MSC_VER >= 1500 only, for OOo 3.0, by adding a virtual destructor to com::sun::star::uno::Exception?

- The C++ UNO bridge could be vastly simplified, in that we no longer need SEH and fiddling with the internals of the msvcr C++ exception handling to obtain the RTTI of a thrown exception.

- All involved OOo code (URE, etc.) is recompiled for OOo 3.0, anyway, so OOo code itself would not be affected by the incompatibility of the change.

- What about existing C++ extensions?
-- If they were built with an older compiler, they will not work, in general, anyway: --- For one, the necessary runtime libraries for the older compiler will probably not be available (see <http://www.openoffice.org/issues/show_bug.cgi?id=88329>). --- For another, and this just dawned on me, the C++ UNO bridge (msci_uno.dll) already does not handle them correctly in all cases. The reason is that there is only a single bridge instance for all compiler versions per process (the one msci_uno.dll contained in an OOo installation set), but its code is actually compiler dependent (see all the #if _MSC_VER stuff in bridges/source/cpp_uno/msvc_win32_intel/except.cxx:1.17). -- If they were built with the latest compiler but before the incompatible change to com::sun::star::uno::Exception is made, they will have to be rebuilt (which implies that you should probably not distribute such extensions until this problem has settled on a decent solution...).

Thoughts, anyone?
-Stephan

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to