Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e5da4ef9 authored by John Reck's avatar John Reck
Browse files

Trap SIGABRT in RenderThread for unit tests

Change-Id: Icc1039543d975497808a8062e9d909537c4a29c9
parent a5abf801
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -225,6 +225,7 @@ LOCAL_SRC_FILES += \
    $(hwui_test_common_src_files) \
    tests/unit/CanvasStateTests.cpp \
    tests/unit/ClipAreaTests.cpp \
    tests/unit/CrashHandlerInjector.cpp \
    tests/unit/DamageAccumulatorTests.cpp \
    tests/unit/DeviceInfoTests.cpp \
    tests/unit/FatVectorTests.cpp \
+40 −0
Original line number Diff line number Diff line
@@ -19,6 +19,10 @@
#include "DeferredLayerUpdater.h"
#include "LayerRenderer.h"

#include <unistd.h>
#include <signal.h>
#include <setjmp.h>

namespace android {
namespace uirenderer {

@@ -121,5 +125,41 @@ void TestUtils::drawTextToCanvas(TestCanvas* canvas, const char* text,
    canvas->drawTextOnPath(glyphs.data(), glyphs.size(), path, 0, 0, paint);
}

static void defaultCrashHandler() {
    fprintf(stderr, "RenderThread crashed!");
}

static jmp_buf gErrJmpBuff;
static std::function<void()> gCrashHandler = defaultCrashHandler;

static void signalHandler(int sig) {
    longjmp(gErrJmpBuff, 1);
}

void TestUtils::setRenderThreadCrashHandler(std::function<void()> crashHandler) {
    gCrashHandler = crashHandler;
}

void TestUtils::TestTask::run() {
    struct sigaction act;
    memset(&act, 0, sizeof(act));
    act.sa_handler = signalHandler;

    if (setjmp(gErrJmpBuff)) {
        gCrashHandler();
        return;
    }

    sigaction(SIGABRT, &act, nullptr);


    // RenderState only valid once RenderThread is running, so queried here
    RenderState& renderState = renderthread::RenderThread::getInstance().renderState();

    renderState.onGLContextCreated();
    rtCallback(renderthread::RenderThread::getInstance());
    renderState.onGLContextDestroyed();
}

} /* namespace uirenderer */
} /* namespace android */
+3 −8
Original line number Diff line number Diff line
@@ -173,19 +173,14 @@ public:

    typedef std::function<void(renderthread::RenderThread& thread)> RtCallback;

    static void setRenderThreadCrashHandler(std::function<void()> crashHandler);

    class TestTask : public renderthread::RenderTask {
    public:
        TestTask(RtCallback rtCallback)
                : rtCallback(rtCallback) {}
        virtual ~TestTask() {}
        virtual void run() override {
            // RenderState only valid once RenderThread is running, so queried here
            RenderState& renderState = renderthread::RenderThread::getInstance().renderState();

            renderState.onGLContextCreated();
            rtCallback(renderthread::RenderThread::getInstance());
            renderState.onGLContextDestroyed();
        };
        virtual void run() override;
        RtCallback rtCallback;
    };

+36 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "tests/common/TestUtils.h"

#include <gtest/gtest.h>

using namespace android::uirenderer;

static void gunitCrashHandler() {
    FAIL() << "RenderThread fatal exception!";
}

static void hookError() {
    TestUtils::setRenderThreadCrashHandler(gunitCrashHandler);
}

class HookErrorInit {
public:
    HookErrorInit() { hookError(); }
};

static HookErrorInit sInit;