diff options
-rwxr-xr-x | desktop/scripts/soffice.sh | 2 | ||||
-rw-r--r-- | desktop/source/app/opencl.cxx | 2 | ||||
-rw-r--r-- | include/comphelper/crashzone.hxx | 72 | ||||
-rw-r--r-- | include/opencl/OpenCLZone.hxx | 42 | ||||
-rw-r--r-- | include/sal/log-areas.dox | 1 | ||||
-rw-r--r-- | opencl/source/OpenCLZone.cxx | 10 | ||||
-rw-r--r-- | vcl/Library_vcl.mk | 1 | ||||
-rw-r--r-- | vcl/README.vars | 2 | ||||
-rw-r--r-- | vcl/inc/opengl/watchdog.hxx | 67 | ||||
-rw-r--r-- | vcl/inc/opengl/zone.hxx | 39 | ||||
-rw-r--r-- | vcl/inc/watchdog.hxx | 32 | ||||
-rw-r--r-- | vcl/source/app/svmain.cxx | 8 | ||||
-rw-r--r-- | vcl/source/app/watchdog.cxx | 144 | ||||
-rw-r--r-- | vcl/source/opengl/OpenGLHelper.cxx | 160 |
14 files changed, 318 insertions, 264 deletions
diff --git a/desktop/scripts/soffice.sh b/desktop/scripts/soffice.sh index 415ea047361d..5538c968ee18 100755 --- a/desktop/scripts/soffice.sh +++ b/desktop/scripts/soffice.sh @@ -130,7 +130,7 @@ for arg in "$@" $EXTRAOPT ; do unset MALLOC_CHECK_ MALLOC_PERTURB_ G_SLICE export SAL_DISABLE_FLOATGRAB=1 export OOO_DISABLE_RECOVERY=1 - export SAL_DISABLE_GL_WATCHDOG=1 + export SAL_DISABLE_WATCHDOG=1 export LD_BIND_NOW=1 ;; esac diff --git a/desktop/source/app/opencl.cxx b/desktop/source/app/opencl.cxx index 4cbea032a15c..a1fe3c0f6aea 100644 --- a/desktop/source/app/opencl.cxx +++ b/desktop/source/app/opencl.cxx @@ -193,7 +193,7 @@ void Desktop::CheckOpenCLCompute(const Reference< XDesktop2 > &xDesktop) SAL_INFO("opencl", "Initiating test of OpenCL device"); OpenCLZone aZone; - OpenCLZone::enterInitialTest(); + OpenCLInitialZone aInitialZone; OUString aDevice = officecfg::Office::Calc::Formula::Calculation::OpenCLDevice::get(); OUString aSelectedCLDeviceVersionID; diff --git a/include/comphelper/crashzone.hxx b/include/comphelper/crashzone.hxx new file mode 100644 index 000000000000..6cbbe718f8a4 --- /dev/null +++ b/include/comphelper/crashzone.hxx @@ -0,0 +1,72 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef INCLUDED_COMPHELPER_CRASHZONE_H +#define INCLUDED_COMPHELPER_CRASHZONE_H + +#include <sal/config.h> +#include <sal/types.h> +#include <comphelper/comphelperdllapi.h> + +#include <atomic> +#include <csignal> +#include <type_traits> + +struct CrashWatchdogTimingsValues +{ + /// delays to take various actions in 1/4 of a second increments. + int mnDisableEntries; + int const mnAbortAfter; +}; + +/** + * A generic class for detecting if a given crash or a lock-up came from a specific + * area of code (such as OpenGL). + * Use this helper to track that. + * The class is a template so that there can be multiple instances of static variables. + */ +template <typename Dummy> class CrashZone +{ +// gnEnterCount and gnLeaveCount are accessed both from multiple threads (cf. +// WatchdogThread::execute; so need to be of atomic type) and from signal handlers (cf. +// VCLExceptionSignal_impl; so need to be of lock-free atomic type). sig_atomic_t is chosen as +// the underlying type under the assumption that it is most likely to lead to an atomic type +// that is actually lock-free. However, gnEnterCount and gnLeaveCount are both monotonically +// increasing, so will eventually overflow, so the underlying type better be unsigned, which +// sig_atomic_t is not guaranteed to be: +#if !defined ARM32 || (defined ARM32 && defined __ARM_PCS_VFP) + using AtomicCounter = std::atomic<std::make_unsigned_t<std::sig_atomic_t>>; + static_assert(AtomicCounter::is_always_lock_free); +#else + using AtomicCounter = volatile std::make_unsigned_t<std::sig_atomic_t>; +#endif + + /// how many times have we entered a zone + static inline AtomicCounter gnEnterCount = 0; + /// how many times have we left a new zone + static inline AtomicCounter gnLeaveCount = 0; + +public: + CrashZone() { enter(); } + ~CrashZone() { leave(); } + static bool isInZone() { return gnEnterCount != gnLeaveCount; } + static const AtomicCounter& enterCount() { return gnEnterCount; } + // prefer creating instances to manually calling enter()/leave() + static void enter() { gnEnterCount++; } + static void leave() { gnLeaveCount++; } + // these should be implemented for each specific zone if needed + // static void hardDisable(); + // static const CrashWatchdogTimingsValues& getCrashWatchdogTimingsValues(); + // static void checkDebug(int nUnchanged, const CrashWatchdogTimingsValues& aTimingValues); + // static const char* name(); +}; + +#endif // INCLUDED_COMPHELPER_CRASHZONE_H + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/opencl/OpenCLZone.hxx b/include/opencl/OpenCLZone.hxx index 50d0f81c3191..1bbf3a46161c 100644 --- a/include/opencl/OpenCLZone.hxx +++ b/include/opencl/OpenCLZone.hxx @@ -12,45 +12,19 @@ #include <sal/config.h> -#include <cassert> -#include <csignal> - #include <opencl/opencldllapi.h> -// FIXME: post back-port, templatize me and share with OpenGLZone. -class OPENCL_DLLPUBLIC OpenCLZone -{ - /// how many times have we entered a CL zone and not yet left it - static volatile std::sig_atomic_t gnEnterCount; - static volatile bool gbInInitialTest; +#include <comphelper/crashzone.hxx> +class OPENCL_DLLPUBLIC OpenCLZone : public CrashZone< OpenCLZone > +{ public: - OpenCLZone() - { - gnEnterCount = gnEnterCount + 1; //TODO: overflow - } - - ~OpenCLZone() - { - // coverity[assert_side_effect] - assert(gnEnterCount > 0); - gnEnterCount = gnEnterCount - 1; - if (!isInZone()) - gbInInitialTest = false; - } - - static bool isInZone() - { - return gnEnterCount > 0; - } - - static bool isInInitialTest() - { - return gbInInitialTest; - } - static void hardDisable(); - static void enterInitialTest(); +}; + +// Used during initial testing of OpenCL. +class OPENCL_DLLPUBLIC OpenCLInitialZone : public CrashZone< OpenCLInitialZone > +{ }; #endif // INCLUDED_OPENCL_INC_OPENCL_ZONE_HXX diff --git a/include/sal/log-areas.dox b/include/sal/log-areas.dox index ce0fa239b292..3ebe47afd2b4 100644 --- a/include/sal/log-areas.dox +++ b/include/sal/log-areas.dox @@ -504,6 +504,7 @@ certain functionality. @li @c vcl.unx.dtrans @li @c vcl.unx.print @li @c vcl.virdev +@li @c vcl.watchdog @li @c vcl.window @li @c vcl.wmf diff --git a/opencl/source/OpenCLZone.cxx b/opencl/source/OpenCLZone.cxx index f7c8e961364d..43ac31899c4d 100644 --- a/opencl/source/OpenCLZone.cxx +++ b/opencl/source/OpenCLZone.cxx @@ -17,11 +17,6 @@ #include <com/sun/star/util/XFlushable.hpp> #include <com/sun/star/configuration/theDefaultProvider.hpp> -// FIXME: templatize me vs. OpenGLZone. - -std::sig_atomic_t volatile OpenCLZone::gnEnterCount = 0; -bool volatile OpenCLZone::gbInInitialTest = false; - /** * Called from a signal handler if we get * a crash or hang in some CL code. @@ -47,9 +42,4 @@ void OpenCLZone::hardDisable() } } -void OpenCLZone::enterInitialTest() -{ - gbInInitialTest = true; -} - /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk index 3a7122f15b11..16be92968a92 100644 --- a/vcl/Library_vcl.mk +++ b/vcl/Library_vcl.mk @@ -399,6 +399,7 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\ vcl/source/app/unohelp2 \ vcl/source/app/unohelp \ vcl/source/app/vclevent \ + vcl/source/app/watchdog \ vcl/source/app/weldutils \ vcl/source/app/winscheduler \ vcl/source/components/dtranscomp \ diff --git a/vcl/README.vars b/vcl/README.vars index 538c6975f26d..495c9679e401 100644 --- a/vcl/README.vars +++ b/vcl/README.vars @@ -36,7 +36,7 @@ OpenGL SAL_FORCEGL - force enable OpenGL SAL_GL_NO_SWAP - disable buffer swapping if set (should show nothing) SAL_GL_SLEEP_ON_SWAP - sleep for half a second on each swap-buffers. -SAL_DISABLE_GL_WATCHDOG - don't start the thread that watches for broken GL drivers +SAL_DISABLE_WATCHDOG - don't start the thread that watches for broken GL/Vulkan/OpenCL drivers Skia ---- diff --git a/vcl/inc/opengl/watchdog.hxx b/vcl/inc/opengl/watchdog.hxx deleted file mode 100644 index a675894c4ff3..000000000000 --- a/vcl/inc/opengl/watchdog.hxx +++ /dev/null @@ -1,67 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -#ifndef INCLUDED_VCL_INC_OPENGL_WATCHDOG_H -#define INCLUDED_VCL_INC_OPENGL_WATCHDOG_H - -#include <sal/config.h> -#include <salhelper/thread.hxx> -#include <atomic> -#include <vector> - -struct WatchdogTimingsValues -{ - /// delays to take various actions in 1/4 of a second increments. - int mnDisableEntries; - int const mnAbortAfter; -}; - -enum class WatchdogTimingMode -{ - NORMAL, - SHADER_COMPILE -}; - -class WatchdogTimings -{ -private: - std::vector<WatchdogTimingsValues> maTimingValues; - std::atomic<bool> mbRelaxed; - -public: - WatchdogTimings(); - - void setRelax(bool bRelaxed) - { - mbRelaxed = bRelaxed; - } - - WatchdogTimingsValues const & getWatchdogTimingsValues(WatchdogTimingMode eMode) - { - size_t index = (eMode == WatchdogTimingMode::SHADER_COMPILE) ? 1 : 0; - index = mbRelaxed ? index + 2 : index; - - return maTimingValues[index]; - } -}; - -class OpenGLWatchdogThread : private salhelper::Thread -{ - OpenGLWatchdogThread(); - virtual void execute() override; -public: - using salhelper::Thread::acquire; - using salhelper::Thread::release; - static void start(); - static void stop(); -}; - -#endif // INCLUDED_VCL_INC_OPENGL_WATCHDOG_H - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/inc/opengl/zone.hxx b/vcl/inc/opengl/zone.hxx index 90b7f48fd5a8..621ee4289b27 100644 --- a/vcl/inc/opengl/zone.hxx +++ b/vcl/inc/opengl/zone.hxx @@ -13,48 +13,19 @@ #include <sal/config.h> #include <sal/types.h> #include <vcl/dllapi.h> - -#include <atomic> -#include <csignal> -#include <type_traits> - -class OpenGLWatchdogThread; +#include <comphelper/crashzone.hxx> /** * We want to be able to detect if a given crash came * from the OpenGL code, so use this helper to track that. */ -class VCL_DLLPUBLIC OpenGLZone { - friend class OpenGLWatchdogThread; - friend class OpenGLSalGraphicsImpl; - - // gnEnterCount and gnLeaveCount are accessed both from multiple threads (cf. - // OpenGLWatchdogThread::execute; so need to be of atomic type) and from signal handlers (cf. - // VCLExceptionSignal_impl; so need to be of lock-free atomic type). sig_atomic_t is chosen as - // the underlying type under the assumption that it is most likely to lead to an atomic type - // that is actually lock-free. However, gnEnterCount and gnLeaveCount are both monotonically - // increasing, so will eventually overflow, so the underlying type better be unsigned, which - // sig_atomic_t is not guaranteed to be: -#if !defined ARM32 || (defined ARM32 && defined __ARM_PCS_VFP) - using AtomicCounter = std::atomic<std::make_unsigned_t<std::sig_atomic_t>>; - static_assert(AtomicCounter::is_always_lock_free); -#else - using AtomicCounter = volatile std::make_unsigned_t<std::sig_atomic_t>; -#endif - - /// how many times have we entered a GL zone - static AtomicCounter gnEnterCount; - /// how many times have we left a new GL zone - static AtomicCounter gnLeaveCount; - - static void enter() { gnEnterCount++; } - static void leave() { gnLeaveCount++; } +class VCL_DLLPUBLIC OpenGLZone : public CrashZone< OpenGLZone > { public: - OpenGLZone() { enter(); } - ~OpenGLZone() { leave(); } - static bool isInZone() { return gnEnterCount != gnLeaveCount; } static void hardDisable(); static void relaxWatchdogTimings(); + static const CrashWatchdogTimingsValues& getCrashWatchdogTimingsValues(); + static void checkDebug( int nUnchanged, const CrashWatchdogTimingsValues& aTimingValues ); + static const char* name() { return "OpenGL"; } }; /// Create this to not only enter the zone, but set VCL context. diff --git a/vcl/inc/watchdog.hxx b/vcl/inc/watchdog.hxx new file mode 100644 index 000000000000..ee357fb2dc89 --- /dev/null +++ b/vcl/inc/watchdog.hxx @@ -0,0 +1,32 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef INCLUDED_VCL_INC_WATCHDOG_H +#define INCLUDED_VCL_INC_WATCHDOG_H + +#include <sal/config.h> +#include <salhelper/thread.hxx> +#include <atomic> +#include <vector> + +class WatchdogThread : private salhelper::Thread +{ + WatchdogThread(); + virtual void execute() override; + +public: + using salhelper::Thread::acquire; + using salhelper::Thread::release; + static void start(); + static void stop(); +}; + +#endif // INCLUDED_VCL_INC_WATCHDOG_H + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/app/svmain.cxx b/vcl/source/app/svmain.cxx index b8c97d08d9c8..207a6ff4eaad 100644 --- a/vcl/source/app/svmain.cxx +++ b/vcl/source/app/svmain.cxx @@ -88,7 +88,7 @@ #include <opencl/OpenCLZone.hxx> #include <opengl/zone.hxx> -#include <opengl/watchdog.hxx> +#include <watchdog.hxx> #include <basegfx/utils/systemdependentdata.hxx> #include <tools/diagnose_ex.h> @@ -128,7 +128,7 @@ static oslSignalAction VCLExceptionSignal_impl( void* /*pData*/, oslSignalInfo* { OpenCLZone::hardDisable(); #ifdef _WIN32 - if (OpenCLZone::isInInitialTest()) + if (OpenCLInitialZone::isInZone()) TerminateProcess(GetCurrentProcess(), EXITHELPER_NORMAL_RESTART); #endif } @@ -212,9 +212,7 @@ int ImplSVMain() pSVData->mxAccessBridge.clear(); } -#if HAVE_FEATURE_OPENGL - OpenGLWatchdogThread::stop(); -#endif + WatchdogThread::stop(); DeInitVCL(); return nReturn; diff --git a/vcl/source/app/watchdog.cxx b/vcl/source/app/watchdog.cxx new file mode 100644 index 000000000000..c6c43e7e013b --- /dev/null +++ b/vcl/source/app/watchdog.cxx @@ -0,0 +1,144 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <watchdog.hxx> + +#include <config_features.h> + +#include <osl/conditn.hxx> +#include <rtl/ref.hxx> +#include <rtl/string.hxx> +#include <sal/log.hxx> +#include <opengl/zone.hxx> + +#include <stdlib.h> + +namespace +{ +static volatile bool gbWatchdogFiring = false; +static osl::Condition* gpWatchdogExit = nullptr; +static rtl::Reference<WatchdogThread> gxWatchdog; + +template <typename Zone> struct WatchdogHelper +{ + static inline sal_uInt64 nLastEnters = 0; + static inline int nUnchanged = 0; // how many unchanged nEnters + static inline bool bFired = false; + static inline bool bAbortFired = false; + static void setLastEnters() { nLastEnters = Zone::enterCount(); } + static void check() + { + if (Zone::isInZone()) + { + const CrashWatchdogTimingsValues& aTimingValues = Zone::getCrashWatchdogTimingsValues(); + + if (nLastEnters == Zone::enterCount()) + nUnchanged++; + else + nUnchanged = 0; + Zone::checkDebug(nUnchanged, aTimingValues); + + // Not making progress + if (nUnchanged >= aTimingValues.mnDisableEntries) + { + if (!bFired) + { + gbWatchdogFiring = true; + SAL_WARN("vcl.watchdog", + OStringLiteral("Watchdog triggered: hard disable ") + Zone::name()); + Zone::hardDisable(); + gbWatchdogFiring = false; + } + bFired = true; + + // we can hang using VCL in the abort handling -> be impatient + if (bAbortFired) + { + SAL_WARN("vcl.watchdog", + OStringLiteral("Watchdog gave up: hard exiting ") + Zone::name()); + _Exit(1); + } + } + + // Not making even more progress + if (nUnchanged >= aTimingValues.mnAbortAfter) + { + if (!bAbortFired) + { + SAL_WARN("vcl.watchdog", + OStringLiteral("Watchdog gave up: aborting ") + Zone::name()); + gbWatchdogFiring = true; + std::abort(); + } + // coverity[dead_error_line] - we might have caught SIGABRT and failed to exit yet + bAbortFired = true; + } + } + else + { + nUnchanged = 0; + } + } +}; + +} // namespace + +WatchdogThread::WatchdogThread() + : salhelper::Thread("Crash Watchdog") +{ +} + +void WatchdogThread::execute() +{ + TimeValue aQuarterSecond(0, 1000 * 1000 * 1000 * 0.25); + do + { +#if HAVE_FEATURE_OPENGL + WatchdogHelper<OpenGLZone>::setLastEnters(); +#endif + + gpWatchdogExit->wait(&aQuarterSecond); + +#if HAVE_FEATURE_OPENGL + WatchdogHelper<OpenGLZone>::check(); +#endif + + } while (!gpWatchdogExit->check()); +} + +void WatchdogThread::start() +{ + if (gxWatchdog != nullptr) + return; // already running + if (getenv("SAL_DISABLE_WATCHDOG")) + return; + gpWatchdogExit = new osl::Condition(); + gxWatchdog.set(new WatchdogThread()); + gxWatchdog->launch(); +} + +void WatchdogThread::stop() +{ + if (gbWatchdogFiring) + return; // in watchdog thread + + if (gpWatchdogExit) + gpWatchdogExit->set(); + + if (gxWatchdog.is()) + { + gxWatchdog->join(); + gxWatchdog.clear(); + } + + delete gpWatchdogExit; + gpWatchdogExit = nullptr; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/opengl/OpenGLHelper.cxx b/vcl/source/opengl/OpenGLHelper.cxx index 1c9fa66436c8..081bf240cc8b 100644 --- a/vcl/source/opengl/OpenGLHelper.cxx +++ b/vcl/source/opengl/OpenGLHelper.cxx @@ -29,12 +29,11 @@ #include <unordered_map> #include <opengl/zone.hxx> -#include <opengl/watchdog.hxx> -#include <osl/conditn.hxx> #include <vcl/opengl/OpenGLWrapper.hxx> #include <vcl/opengl/OpenGLContext.hxx> #include <desktop/crashreport.hxx> #include <bitmapwriteaccess.hxx> +#include <watchdog.hxx> #if defined UNX && !defined MACOSX && !defined IOS && !defined ANDROID && !defined HAIKU #include <opengl/x11/X11DeviceInfo.hxx> @@ -45,8 +44,6 @@ #include "GLMHelper.hxx" static bool volatile gbInShaderCompile = false; -OpenGLZone::AtomicCounter OpenGLZone::gnEnterCount = 0; -OpenGLZone::AtomicCounter OpenGLZone::gnLeaveCount = 0; namespace { @@ -793,121 +790,50 @@ bool OpenGLHelper::supportsVCLOpenGL() return !bDisableGL && !bBlacklisted; } -namespace { - static volatile bool gbWatchdogFiring = false; - static osl::Condition* gpWatchdogExit = nullptr; - static WatchdogTimings gWatchdogTimings; - static rtl::Reference<OpenGLWatchdogThread> gxWatchdog; -} - -WatchdogTimings::WatchdogTimings() - : maTimingValues{ - {{6, 20} /* 1.5s, 5s */, {20, 120} /* 5s, 30s */, - {60, 240} /* 15s, 60s */, {60, 240} /* 15s, 60s */} - } - , mbRelaxed(false) +namespace { -} -OpenGLWatchdogThread::OpenGLWatchdogThread() - : salhelper::Thread("OpenGL Watchdog") +enum class CrashWatchdogTimingMode { -} + NORMAL, + SHADER_COMPILE +}; -void OpenGLWatchdogThread::execute() +class CrashWatchdogTimings { - int nUnchanged = 0; // how many unchanged nEnters - TimeValue aQuarterSecond(0, 1000*1000*1000*0.25); - bool bAbortFired = false; +private: + std::vector<CrashWatchdogTimingsValues> maTimingValues; + std::atomic<bool> mbRelaxed; - do { - sal_uInt64 nLastEnters = OpenGLZone::gnEnterCount; +public: + CrashWatchdogTimings(); - gpWatchdogExit->wait(&aQuarterSecond); + void setRelax(bool bRelaxed) + { + mbRelaxed = bRelaxed; + } - if (OpenGLZone::isInZone()) - { - // The shader compiler can take a long time, first time. - WatchdogTimingMode eMode = gbInShaderCompile ? WatchdogTimingMode::SHADER_COMPILE : WatchdogTimingMode::NORMAL; - WatchdogTimingsValues aTimingValues = gWatchdogTimings.getWatchdogTimingsValues(eMode); + CrashWatchdogTimingsValues const & getWatchdogTimingsValues(CrashWatchdogTimingMode eMode) + { + size_t index = (eMode == CrashWatchdogTimingMode::SHADER_COMPILE) ? 1 : 0; + index = mbRelaxed ? index + 2 : index; - if (nLastEnters == OpenGLZone::gnEnterCount) - nUnchanged++; - else - nUnchanged = 0; - SAL_INFO("vcl.opengl", "GL watchdog - unchanged " << - nUnchanged << " enter count " << - OpenGLZone::gnEnterCount << " type " << - (eMode == WatchdogTimingMode::SHADER_COMPILE ? "in shader" : "normal gl") << - "breakpoints mid: " << aTimingValues.mnDisableEntries << - " max " << aTimingValues.mnAbortAfter); - - // Not making progress - if (nUnchanged >= aTimingValues.mnDisableEntries) - { - static bool bFired = false; - if (!bFired) - { - gbWatchdogFiring = true; - SAL_WARN("vcl.opengl", "Watchdog triggered: hard disable GL"); - OpenGLZone::hardDisable(); - gbWatchdogFiring = false; - } - bFired = true; - - // we can hang using VCL in the abort handling -> be impatient - if (bAbortFired) - { - SAL_WARN("vcl.opengl", "Watchdog gave up: hard exiting"); - _exit(1); - } - } + return maTimingValues[index]; + } +}; - // Not making even more progress - if (nUnchanged >= aTimingValues.mnAbortAfter) - { - if (!bAbortFired) - { - SAL_WARN("vcl.opengl", "Watchdog gave up: aborting"); - gbWatchdogFiring = true; - std::abort(); - } - // coverity[dead_error_line] - we might have caught SIGABRT and failed to exit yet - bAbortFired = true; - } - } - else - { - nUnchanged = 0; - } - } while (!gpWatchdogExit->check()); -} +static CrashWatchdogTimings gWatchdogTimings; -void OpenGLWatchdogThread::start() +CrashWatchdogTimings::CrashWatchdogTimings() + : maTimingValues{ + {{6, 20} /* 1.5s, 5s */, {20, 120} /* 5s, 30s */, + {60, 240} /* 15s, 60s */, {60, 240} /* 15s, 60s */} + } + , mbRelaxed(false) { - assert (gxWatchdog == nullptr); - gpWatchdogExit = new osl::Condition(); - gxWatchdog.set(new OpenGLWatchdogThread()); - gxWatchdog->launch(); } -void OpenGLWatchdogThread::stop() -{ - if (gbWatchdogFiring) - return; // in watchdog thread - - if (gpWatchdogExit) - gpWatchdogExit->set(); - - if (gxWatchdog.is()) - { - gxWatchdog->join(); - gxWatchdog.clear(); - } - - delete gpWatchdogExit; - gpWatchdogExit = nullptr; -} +} // namespace /** * Called from a signal handler or watchdog thread if we get @@ -932,8 +858,6 @@ void OpenGLZone::hardDisable() css::configuration::theDefaultProvider::get( comphelper::getProcessComponentContext()), css::uno::UNO_QUERY_THROW)->flush(); - - OpenGLWatchdogThread::stop(); } } @@ -942,6 +866,22 @@ void OpenGLZone::relaxWatchdogTimings() gWatchdogTimings.setRelax(true); } +void OpenGLZone::checkDebug( int nUnchanged, const CrashWatchdogTimingsValues& aTimingValues ) +{ + SAL_INFO("vcl.watchdog", "GL watchdog - unchanged " + << nUnchanged << " enter count " << enterCount() << " type " + << (gbInShaderCompile ? "in shader" : "normal gl") + << " breakpoints mid: " << aTimingValues.mnDisableEntries + << " max " << aTimingValues.mnAbortAfter); +} + +const CrashWatchdogTimingsValues& OpenGLZone::getCrashWatchdogTimingsValues() +{ + // The shader compiler can take a long time, first time. + CrashWatchdogTimingMode eMode = gbInShaderCompile ? CrashWatchdogTimingMode::SHADER_COMPILE : CrashWatchdogTimingMode::NORMAL; + return gWatchdogTimings.getWatchdogTimingsValues(eMode); +} + OpenGLVCLContextZone::OpenGLVCLContextZone() { OpenGLContext::makeVCLCurrent(); @@ -1019,10 +959,8 @@ bool OpenGLHelper::isVCLOpenGLEnabled() } if (bRet) - { - if (!getenv("SAL_DISABLE_GL_WATCHDOG")) - OpenGLWatchdogThread::start(); - } + WatchdogThread::start(); + CrashReporter::addKeyValue("UseOpenGL", OUString::boolean(bRet), CrashReporter::Write); return bRet; |