Stephan Bergmann wrote:
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.)
The last part (about the C++ Runtime itself working it out correctly),
appears to be false, after all. Stripping down soffice as follows makes
the problem appear, without any C++ UNO bridge involved:
soffice.bin just calls soffice_main in soffice.dll; soffice.dll is
stripped to just soffice_main, which in turn is stripped to just
try {
throw 1;
} catch (int &) {
TESTIT();
}
where sal3.dll is stripped to just contain function TESTIT which does
try {
throw;
} catch (int &) {}
The resulting soffice.bin and soffice.dll are placed in C:\TEST
(together with the MS runtime libs), sal3.dll is placed in C:\TEST\sub
(also together with the MS runtime libs), PATH is set to just
C:\TEST\sub, and C:\TEST\soffice.bin is executed---and crashes between
the re-throw in sal3.dll and the corresponding catch.
The interesting thing, however, is that if I re-build this test scenario
from scratch, with a main.exe and first.dll and second.dll
(corresponding to soffice.bin, soffice.dll, sal3.dll, resp.) built "by
hand" (without many of the switches used in the OOo build env.)---then
it works! I then do not even need the MS runtime libs in the
C:\TEST\sub directory, the process starts happily with the runtime libs
just in the C:\TEST directory next to the executable, and the re-thrown
exception is caught.
So, maybe there is still hope, if we can identify the critical
difference in the build environments for the two scenarios, and adapt
the OOo build env. correspondingly...
-Stephan
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]