Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/LibreOffice/vcl/source/app/   (Office von Apache Version 25.8.3.2©)  Datei vom 5.10.2025 mit Größe 4 kB image not shown  

Quelle  watchdog.cxx   Sprache: C

 
/* -*- 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 <comphelper/debuggerinfo.hxx>
#include <opengl/zone.hxx>
#include <skia/zone.hxx>

#include <stdlib.h>

#if defined HAVE_VALGRIND_HEADERS
#include <valgrind/memcheck.h>
#endif

#include <atomic>

namespace
{
std::atomic<bool> gbWatchdogFiring = false;
osl::Condition* gpWatchdogExit = nullptr;
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""Watchdog triggered: hard disable " << Zone::name());
#ifdef DBG_UTIL
                    std::abort();
#else
                    Zone::hardDisable();
                    gbWatchdogFiring = false;
#endif
                }
                bFired = true;

                // we can hang using VCL in the abort handling -> be impatient
                if (bAbortFired)
                {
                    SAL_WARN("vcl.watchdog""Watchdog gave up: hard exiting " << Zone::name());
                    _Exit(1);
                }
            }

            // Not making even more progress
            if (nUnchanged >= aTimingValues.mnAbortAfter)
            {
                if (!bAbortFired)
                {
                    SAL_WARN("vcl.watchdog""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
#if HAVE_FEATURE_SKIA
        WatchdogHelper<SkiaZone>::setLastEnters();
#endif

        gpWatchdogExit->wait(&aQuarterSecond);

#if defined HAVE_VALGRIND_HEADERS
        if (RUNNING_ON_VALGRIND)
            continue;
#endif
#if defined DBG_UTIL
        if (comphelper::isDebuggerAttached())
            continue;
#endif

#if HAVE_FEATURE_OPENGL
        WatchdogHelper<OpenGLZone>::check();
#endif
#if HAVE_FEATURE_SKIA
        WatchdogHelper<SkiaZone>::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: */

Messung V0.5
C=94 H=96 G=94

¤ Dauer der Verarbeitung: 0.0 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.