diff options
author | Stephan Bergmann <sbergman@redhat.com> | 2012-09-18 12:40:57 +0200 |
---|---|---|
committer | Stephan Bergmann <sbergman@redhat.com> | 2012-09-18 15:08:56 +0200 |
commit | cccc6bcfa095121c91e8bbc396f5bcf7e95424b9 (patch) | |
tree | f94a97a9698e3376405a36decc7612a2c523c9fd /desktop | |
parent | a0659cc41d7764dd104bce82f8c5b3f0b8073173 (diff) |
Don't access broken service mgr during bootstrap failure
...so that displaying a (non-translated) error box upon BE_UNO_SERVICEMANAGER
works after all. Augment the error text with an exception message where
appropriate. This allows to revert fdfb7a3c4b3a89b73ab5546b9620348bc4984d8f
"Related fdo#51252: Report uncaught exceptions with MessageBox on Windows" as
that was to catch and display failures from instantiating the service mgr.
Change-Id: I049a38e95342634796eb0e940e2ee8e55193c9d3
Diffstat (limited to 'desktop')
-rw-r--r-- | desktop/inc/app.hxx | 19 | ||||
-rw-r--r-- | desktop/source/app/app.cxx | 139 | ||||
-rw-r--r-- | desktop/source/app/desktop.hrc | 1 | ||||
-rw-r--r-- | desktop/source/app/desktop.src | 5 | ||||
-rwxr-xr-x | desktop/source/app/sofficemain.cxx | 21 |
5 files changed, 77 insertions, 108 deletions
diff --git a/desktop/inc/app.hxx b/desktop/inc/app.hxx index 8fd717ec6f18..b1577b2afbe1 100644 --- a/desktop/inc/app.hxx +++ b/desktop/inc/app.hxx @@ -103,15 +103,16 @@ class Desktop : public Application static ResMgr* GetDesktopResManager(); static CommandLineArgs& GetCommandLineArgs(); - void HandleBootstrapErrors( BootstrapError ); - void SetBootstrapError( BootstrapError nError ) + void HandleBootstrapErrors( + BootstrapError nError, OUString const & aMessage ); + void SetBootstrapError( + BootstrapError nError, OUString const & aMessage ) { if ( m_aBootstrapError == BE_OK ) + { m_aBootstrapError = nError; - } - BootstrapError GetBootstrapError() const - { - return m_aBootstrapError; + m_aBootstrapErrorMessage = aMessage; + } } void SetBootstrapStatus( BootstrapStatus nStatus ) @@ -135,8 +136,6 @@ class Desktop : public Application void SetSplashScreenText( const ::rtl::OUString& rText ); void SetSplashScreenProgress( sal_Int32 ); - static void ensureProcessServiceFactory(); - private: // Bootstrap methods static ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > CreateApplicationServiceManager(); @@ -159,9 +158,6 @@ class Desktop : public Application void HandleBootstrapPathErrors( ::utl::Bootstrap::Status, const ::rtl::OUString& aMsg ); void StartSetup( const ::rtl::OUString& aParameters ); - // Get a resource message string securely e.g. if resource cannot be retrieved return aFaultBackMsg - ::rtl::OUString GetMsgString( sal_uInt16 nId, const ::rtl::OUString& aFaultBackMsg ); - // Create a error message depending on bootstrap failure code and an optional file url ::rtl::OUString CreateErrorMsgString( utl::Bootstrap::FailureCode nFailureCode, const ::rtl::OUString& aFileURL ); @@ -200,6 +196,7 @@ class Desktop : public Application bool m_bCleanedExtensionCache; bool m_bServicesRegistered; BootstrapError m_aBootstrapError; + OUString m_aBootstrapErrorMessage; BootstrapStatus m_aBootstrapStatus; std::auto_ptr< Lockfile > m_pLockfile; diff --git a/desktop/source/app/app.cxx b/desktop/source/app/app.cxx index 1781d66b1e1a..fad99085058a 100644 --- a/desktop/source/app/app.cxx +++ b/desktop/source/app/app.cxx @@ -378,28 +378,34 @@ ResMgr* Desktop::GetDesktopResManager() return Desktop::pResMgr; } +namespace { + // ---------------------------------------------------------------------------- // Get a message string securely. There is a fallback string if the resource // is not available. -OUString Desktop::GetMsgString( sal_uInt16 nId, const OUString& aFaultBackMsg ) +OUString GetMsgString( + sal_uInt16 nId, const OUString& aFaultBackMsg, + bool bAlwaysUseFaultBackMsg = false ) { - ResMgr* resMgr = GetDesktopResManager(); - if ( !resMgr ) - return aFaultBackMsg; - else - return OUString( String( ResId( nId, *resMgr ))); + if ( !bAlwaysUseFaultBackMsg ) + { + ResMgr* resMgr = Desktop::GetDesktopResManager(); + if ( resMgr ) + return OUString( String( ResId( nId, *resMgr ))); + } + return aFaultBackMsg; } -OUString MakeStartupErrorMessage(OUString const & aErrorMessage) +OUString MakeStartupErrorMessage( + OUString const & aErrorMessage, bool bAlwaysUseFaultBackMsg = false ) { OUStringBuffer aDiagnosticMessage( 100 ); - ResMgr* pResMgr = Desktop::GetDesktopResManager(); - if ( pResMgr ) - aDiagnosticMessage.append( OUString(String(ResId(STR_BOOTSTRAP_ERR_CANNOT_START, *pResMgr))) ); - else - aDiagnosticMessage.appendAscii( "The program cannot be started." ); + aDiagnosticMessage.append( + GetMsgString( + STR_BOOTSTRAP_ERR_CANNOT_START, "The program cannot be started.", + bAlwaysUseFaultBackMsg ) ); aDiagnosticMessage.appendAscii( "\n" ); @@ -468,9 +474,8 @@ static bool ShouldSuppressUI(const CommandLineArgs& rCmdLine) rCmdLine.IsQuickstart(); } -namespace -{ - struct theCommandLineArgs : public rtl::Static< CommandLineArgs, theCommandLineArgs > {}; +struct theCommandLineArgs : public rtl::Static< CommandLineArgs, theCommandLineArgs > {}; + } CommandLineArgs& Desktop::GetCommandLineArgs() @@ -591,29 +596,30 @@ void Desktop::Init() // We need to have service factory before going further, but see fdo#37195. // Doing this will mmap common.rdb, making it not overwritable on windows, // so this can't happen before the synchronization above. Lets rework this - // so that the above is called *from* ensureProcessServiceFactory or + // so that the above is called *from* CreateApplicationServiceManager or // something to enforce this gotcha - ensureProcessServiceFactory(); - - if( !::comphelper::getProcessServiceFactory().is()) + try + { + comphelper::setProcessServiceFactory(CreateApplicationServiceManager()); + } + catch (css::uno::Exception & e) { - OSL_FAIL("Service factory should have been crated in soffice_main()."); - SetBootstrapError( BE_UNO_SERVICEMANAGER ); + SetBootstrapError( BE_UNO_SERVICEMANAGER, e.Message ); } - if ( GetBootstrapError() == BE_OK ) + if ( m_aBootstrapError == BE_OK ) { // prepare language if ( !LanguageSelection::prepareLanguage() ) { if ( LanguageSelection::getStatus() == LanguageSelection::LS_STATUS_CANNOT_DETERMINE_LANGUAGE ) - SetBootstrapError( BE_LANGUAGE_MISSING ); + SetBootstrapError( BE_LANGUAGE_MISSING, OUString() ); else - SetBootstrapError( BE_OFFICECONFIG_BROKEN ); + SetBootstrapError( BE_OFFICECONFIG_BROKEN, OUString() ); } } - if ( GetBootstrapError() == BE_OK ) + if ( m_aBootstrapError == BE_OK ) { const CommandLineArgs& rCmdLineArgs = GetCommandLineArgs(); // start ipc thread only for non-remote offices @@ -621,7 +627,7 @@ void Desktop::Init() OfficeIPCThread::Status aStatus = OfficeIPCThread::EnableOfficeIPCThread(); if ( aStatus == OfficeIPCThread::IPC_STATUS_BOOTSTRAP_ERROR ) { - SetBootstrapError( BE_PATHINFO_MISSING ); + SetBootstrapError( BE_PATHINFO_MISSING, OUString() ); } else if ( aStatus == OfficeIPCThread::IPC_STATUS_2ND_OFFICE ) { @@ -644,29 +650,6 @@ void Desktop::InitFinished() CloseSplashScreen(); } -// GetCommandLineArgs() requires this code to work, otherwise it will abort, and -// on Unix command line args needs to be checked before Desktop::Init() -void Desktop::ensureProcessServiceFactory() -{ - if (!comphelper::getProcessServiceFactory().is()) - { - try - { - comphelper::setProcessServiceFactory( - CreateApplicationServiceManager()); - } - catch (const css::uno::Exception& e) - { - // Application::ShowNativeErrorBox would only work after InitVCL, so - // all we can realistically do here is hope the user can see stderr: - std::cerr << "UNO Exception: " << e.Message << std::endl; - // Let exceptions escape and tear down the process, it is completely - // broken anyway: - throw; - } - } -} - void Desktop::DeInit() { RTL_LOGFILE_CONTEXT( aLog, "desktop (cd100003) ::Desktop::DeInit" ); @@ -881,7 +864,8 @@ void Desktop::HandleBootstrapPathErrors( ::utl::Bootstrap::Status aBootstrapStat return MakeStartupErrorMessage( aMsg ); } -void Desktop::HandleBootstrapErrors( BootstrapError aBootstrapError ) +void Desktop::HandleBootstrapErrors( + BootstrapError aBootstrapError, OUString const & aErrorMessage ) { if ( aBootstrapError == BE_PATHINFO_MISSING ) { @@ -962,16 +946,18 @@ void Desktop::HandleBootstrapErrors( BootstrapError aBootstrapError ) // PropertyValue is available). To give the user a hint even if // generating and displaying a message box below crashes, print a // hard-coded message on stderr first: - fputs( - aBootstrapError == BE_UNO_SERVICEMANAGER - ? ("The application cannot be started. " "\n" - "The component manager is not available." "\n") - // STR_BOOTSTRAP_ERR_CANNOT_START, STR_BOOTSTRAP_ERR_NO_SERVICE - : ("The application cannot be started. " "\n" - "The configuration service is not available." "\n"), - // STR_BOOTSTRAP_ERR_CANNOT_START, - // STR_BOOTSTRAP_ERR_NO_CFG_SERVICE - stderr); + std::cerr + << "The application cannot be started.\n" + // STR_BOOTSTRAP_ERR_CANNOT_START + << (aBootstrapError == BE_UNO_SERVICEMANAGER + ? "The component manager is not available.\n" + // STR_BOOTSTRAP_ERR_NO_SERVICE + : "The configuration service is not available.\n"); + // STR_BOOTSTRAP_ERR_NO_CFG_SERVICE + if ( !aErrorMessage.isEmpty() ) + { + std::cerr << "(\"" << aErrorMessage << "\")\n"; + } // First sentence. We cannot bootstrap office further! OUString aMessage; @@ -980,24 +966,32 @@ void Desktop::HandleBootstrapErrors( BootstrapError aBootstrapError ) OUString aErrorMsg; if ( aBootstrapError == BE_UNO_SERVICEMANAGER ) - aErrorMsg = GetMsgString( STR_BOOTSTRAP_ERR_NO_SERVICE, - OUString( "The service manager is not available." ) ); + aErrorMsg = "The service manager is not available."; else aErrorMsg = GetMsgString( STR_BOOTSTRAP_ERR_NO_CFG_SERVICE, OUString( "The configuration service is not available." ) ); aDiagnosticMessage.append( aErrorMsg ); aDiagnosticMessage.appendAscii( "\n" ); + if ( !aErrorMessage.isEmpty() ) + { + aDiagnosticMessage.appendAscii( "(\"" ); + aDiagnosticMessage.append( aErrorMessage ); + aDiagnosticMessage.appendAscii( "\")\n" ); + } // Due to the fact the we haven't a backup applicat.rdb file anymore it is not possible to // repair the installation with the setup executable besides the office executable. Now // we have to ask the user to start the setup on CD/installation directory manually!! OUString aStartSetupManually( GetMsgString( STR_ASK_START_SETUP_MANUALLY, - OUString( "Start setup application to repair the installation from CD, or the folder containing the installation packages." ) )); + OUString( "Start setup application to repair the installation from CD, or the folder containing the installation packages." ), + aBootstrapError == BE_UNO_SERVICEMANAGER ) ); aDiagnosticMessage.append( aStartSetupManually ); - aMessage = MakeStartupErrorMessage( aDiagnosticMessage.makeStringAndClear() ); + aMessage = MakeStartupErrorMessage( + aDiagnosticMessage.makeStringAndClear(), + aBootstrapError == BE_UNO_SERVICEMANAGER ); FatalError( aMessage); } @@ -1378,10 +1372,9 @@ int Desktop::Main() com::sun::star::uno::ContextLayer layer( com::sun::star::uno::getCurrentContext() ); - BootstrapError eError = GetBootstrapError(); - if ( eError != BE_OK ) + if ( m_aBootstrapError != BE_OK ) { - HandleBootstrapErrors( eError ); + HandleBootstrapErrors( m_aBootstrapError, m_aBootstrapErrorMessage ); return EXIT_FAILURE; } @@ -1415,11 +1408,12 @@ int Desktop::Main() { OSL_FAIL("userinstall failed"); if ( inst_fin == UserInstall::E_NoDiskSpace ) - HandleBootstrapErrors( BE_USERINSTALL_NOTENOUGHDISKSPACE ); + HandleBootstrapErrors( + BE_USERINSTALL_NOTENOUGHDISKSPACE, OUString() ); else if ( inst_fin == UserInstall::E_NoWriteAccess ) - HandleBootstrapErrors( BE_USERINSTALL_NOWRITEACCESS ); + HandleBootstrapErrors( BE_USERINSTALL_NOWRITEACCESS, OUString() ); else - HandleBootstrapErrors( BE_USERINSTALL_FAILED ); + HandleBootstrapErrors( BE_USERINSTALL_FAILED, OUString() ); return EXIT_FAILURE; } // refresh path information @@ -1797,9 +1791,10 @@ bool Desktop::InitializeConfiguration() comphelper::getProcessComponentContext() ); return true; } - catch( const ::com::sun::star::lang::ServiceNotRegisteredException& ) + catch( ::com::sun::star::lang::ServiceNotRegisteredException & e ) { - this->HandleBootstrapErrors( Desktop::BE_UNO_SERVICE_CONFIG_MISSING ); + this->HandleBootstrapErrors( + Desktop::BE_UNO_SERVICE_CONFIG_MISSING, e.Message ); } catch( const ::com::sun::star::configuration::MissingBootstrapFileException& e ) { diff --git a/desktop/source/app/desktop.hrc b/desktop/source/app/desktop.hrc index 3b01f2444db1..5551db8c2c80 100644 --- a/desktop/source/app/desktop.hrc +++ b/desktop/source/app/desktop.hrc @@ -51,7 +51,6 @@ #define STR_BOOTSTRAP_ERR_NO_SUPPORT (RID_DESKTOP_STRING_START+107) #define STR_BOOTSTRAP_ERR_LANGUAGE_MISSING (RID_DESKTOP_STRING_START+108) -#define STR_BOOTSTRAP_ERR_NO_SERVICE (RID_DESKTOP_STRING_START+120) #define STR_BOOTSTRAP_ERR_NO_CFG_SERVICE (RID_DESKTOP_STRING_START+121) #define STR_BOOTSTRAP_ERR_CFG_DATAACCESS (RID_DESKTOP_STRING_START+122) #define STR_BOOTSTRAP_ERR_NO_PATHSET_SERVICE (RID_DESKTOP_STRING_START+123) diff --git a/desktop/source/app/desktop.src b/desktop/source/app/desktop.src index 67651bc96f84..4e4270fcff4c 100644 --- a/desktop/source/app/desktop.src +++ b/desktop/source/app/desktop.src @@ -88,11 +88,6 @@ String STR_BOOTSTRAP_ERR_LANGUAGE_MISSING Text [ en-US ] = "The user interface language cannot be determined."; }; -String STR_BOOTSTRAP_ERR_NO_SERVICE -{ - Text [ en-US ] = "The component manager is not available."; -}; - String STR_BOOTSTRAP_ERR_NO_CFG_SERVICE { Text [ en-US ] = "The configuration service is not available."; diff --git a/desktop/source/app/sofficemain.cxx b/desktop/source/app/sofficemain.cxx index a0fba044922e..e867601df0ee 100755 --- a/desktop/source/app/sofficemain.cxx +++ b/desktop/source/app/sofficemain.cxx @@ -38,21 +38,14 @@ #include <rtl/bootstrap.hxx> #include <tools/extendapplicationenvironment.hxx> -#if defined WNT -#define WIN32_LEAN_AND_MEAN -#include <windows.h> -#endif - int SVMain(); // -=-= main() -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= extern "C" int DESKTOP_DLLPUBLIC soffice_main() { -#if defined ANDROID || defined WNT +#if defined ANDROID try { -#endif -#if defined(ANDROID) rtl::Bootstrap::setIniFilename( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("file:///assets/program/lofficerc"))); #endif @@ -83,20 +76,10 @@ extern "C" int DESKTOP_DLLPUBLIC soffice_main() } #endif return SVMain(); -#if defined ANDROID || defined WNT - } catch (const ::com::sun::star::uno::Exception &e) { #if defined ANDROID + } catch (const ::com::sun::star::uno::Exception &e) { fprintf (stderr, "Not handled UNO exception at main: '%s'\n", rtl::OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8).getStr()); -#elif defined WNT - MessageBoxW( - 0, - reinterpret_cast< LPCWSTR >( - rtl::OUString("Unhandled exception:\n" + e.Message).getStr()), - reinterpret_cast< LPCWSTR >(rtl::OUString("Fatal Error").getStr()), - (MB_OK | MB_ICONERROR | MB_DEFBUTTON1 | MB_TASKMODAL - | MB_SETFOREGROUND | MB_TOPMOST)); -#endif throw; // to get exception type printed } #endif |