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]