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]

Reply via email to