SurfaceFlinger: add stack guards around SurfaceFlinger::postComposition

This is a debug patch for b/119477596 to try to catch a stack
corruption.

Test: Monkey
Change-Id: I270ace2660de7bab4a58deb2088275c2acc81be4
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index dc82b32..5cac524 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -52,6 +52,7 @@
 #include <ui/GraphicBufferAllocator.h>
 #include <ui/PixelFormat.h>
 #include <ui/UiConfig.h>
+#include <utils/CallStack.h>
 #include <utils/StopWatch.h>
 #include <utils/String16.h>
 #include <utils/String8.h>
@@ -1876,22 +1877,78 @@
     getBE().mCompositorTiming.presentLatency = snappedCompositeToPresentLatency;
 }
 
+// debug patch for b/119477596 - add stack guards to catch stack
+// corruptions and disable clang optimizations.
+// The code below is temporary and planned to be removed once stack
+// corruptions are found.
+#pragma clang optimize off
+class StackGuard {
+public:
+    StackGuard(const char* name, const char* func, int line) {
+        guarders.reserve(MIN_CAPACITY);
+        guarders.push_back({this, name, func, line});
+        validate();
+    }
+    ~StackGuard() {
+        for (auto i = guarders.end() - 1; i >= guarders.begin(); --i) {
+            if (i->guard == this) {
+                guarders.erase(i);
+                break;
+            }
+        }
+    }
+
+    static void validate() {
+        for (const auto& guard : guarders) {
+            if (guard.guard->cookie != COOKIE_VALUE) {
+                ALOGE("%s:%d: Stack corruption detected at %s", guard.func, guard.line, guard.name);
+                CallStack stack(LOG_TAG);
+                abort();
+            }
+        }
+    }
+
+private:
+    uint64_t cookie = COOKIE_VALUE;
+    static constexpr uint64_t COOKIE_VALUE = 0xc0febebedeadbeef;
+    static constexpr size_t MIN_CAPACITY = 16;
+
+    struct GuarderElement {
+        StackGuard* guard;
+        const char* name;
+        const char* func;
+        int line;
+    };
+
+    static std::vector<GuarderElement> guarders;
+};
+std::vector<StackGuard::GuarderElement> StackGuard::guarders;
+
+#define DEFINE_STACK_GUARD(__n) StackGuard __n##StackGuard(#__n, __FUNCTION__, __LINE__);
+
+#define ASSERT_ON_STACK_GUARD() StackGuard::validate();
 void SurfaceFlinger::postComposition()
 {
+    DEFINE_STACK_GUARD(begin);
     ATRACE_CALL();
     ALOGV("postComposition");
 
     // Release any buffers which were replaced this frame
     nsecs_t dequeueReadyTime = systemTime();
+    DEFINE_STACK_GUARD(dequeueReadyTime);
     for (auto& layer : mLayersWithQueuedFrames) {
         layer->releasePendingBuffer(dequeueReadyTime);
     }
+    ASSERT_ON_STACK_GUARD();
 
     // |mStateLock| not needed as we are on the main thread
     const auto display = getDefaultDisplayDeviceLocked();
+    DEFINE_STACK_GUARD(display);
 
     getBE().mGlCompositionDoneTimeline.updateSignalTimes();
     std::shared_ptr<FenceTime> glCompositionDoneFenceTime;
+    DEFINE_STACK_GUARD(glCompositionDoneFenceTime);
+
     if (display && getHwComposer().hasClientComposition(display->getId())) {
         glCompositionDoneFenceTime =
                 std::make_shared<FenceTime>(display->getClientTargetAcquireFence());
@@ -1900,13 +1957,17 @@
         glCompositionDoneFenceTime = FenceTime::NO_FENCE;
     }
 
+    ASSERT_ON_STACK_GUARD();
+
     getBE().mDisplayTimeline.updateSignalTimes();
     mPreviousPresentFence =
             display ? getHwComposer().getPresentFence(*display->getId()) : Fence::NO_FENCE;
     auto presentFenceTime = std::make_shared<FenceTime>(mPreviousPresentFence);
+    DEFINE_STACK_GUARD(presentFenceTime);
     getBE().mDisplayTimeline.push(presentFenceTime);
 
     DisplayStatInfo stats;
+    DEFINE_STACK_GUARD(stats);
     if (mUseScheduler) {
         mScheduler->getDisplayStatInfo(&stats);
     } else {
@@ -1914,34 +1975,46 @@
         stats.vsyncPeriod = mPrimaryDispSync->getPeriod();
     }
 
+    ASSERT_ON_STACK_GUARD();
+
     // We use the mRefreshStartTime which might be sampled a little later than
     // when we started doing work for this frame, but that should be okay
     // since updateCompositorTiming has snapping logic.
     updateCompositorTiming(stats, mRefreshStartTime, presentFenceTime);
     CompositorTiming compositorTiming;
+    DEFINE_STACK_GUARD(compositorTiming);
+
     {
         std::lock_guard<std::mutex> lock(getBE().mCompositorTimingLock);
+        DEFINE_STACK_GUARD(lock);
         compositorTiming = getBE().mCompositorTiming;
+
+        ASSERT_ON_STACK_GUARD();
     }
 
     mDrawingState.traverseInZOrder([&](Layer* layer) {
         bool frameLatched = layer->onPostComposition(display->getId(), glCompositionDoneFenceTime,
                                                      presentFenceTime, compositorTiming);
+        DEFINE_STACK_GUARD(frameLatched);
         if (frameLatched) {
             recordBufferingStats(layer->getName().string(),
                     layer->getOccupancyHistory(false));
         }
+        ASSERT_ON_STACK_GUARD();
     });
 
     if (presentFenceTime->isValid()) {
+        ASSERT_ON_STACK_GUARD();
         if (mUseScheduler) {
             mScheduler->addPresentFence(presentFenceTime);
+            ASSERT_ON_STACK_GUARD();
         } else {
             if (mPrimaryDispSync->addPresentFence(presentFenceTime)) {
                 enableHardwareVsync();
             } else {
                 disableHardwareVsync(false);
             }
+            ASSERT_ON_STACK_GUARD();
         }
     }
 
@@ -1955,61 +2028,86 @@
         }
     }
 
+    ASSERT_ON_STACK_GUARD();
+
     if (mAnimCompositionPending) {
         mAnimCompositionPending = false;
 
         if (presentFenceTime->isValid()) {
             mAnimFrameTracker.setActualPresentFence(
                     std::move(presentFenceTime));
+
+            ASSERT_ON_STACK_GUARD();
         } else if (display && getHwComposer().isConnected(*display->getId())) {
             // The HWC doesn't support present fences, so use the refresh
             // timestamp instead.
             const nsecs_t presentTime = getHwComposer().getRefreshTimestamp(*display->getId());
+            DEFINE_STACK_GUARD(presentTime);
+
             mAnimFrameTracker.setActualPresentTime(presentTime);
+            ASSERT_ON_STACK_GUARD();
         }
         mAnimFrameTracker.advanceFrame();
     }
 
+    ASSERT_ON_STACK_GUARD();
+
     mTimeStats->incrementTotalFrames();
     if (mHadClientComposition) {
         mTimeStats->incrementClientCompositionFrames();
     }
 
+    ASSERT_ON_STACK_GUARD();
+
     mTimeStats->setPresentFenceGlobal(presentFenceTime);
 
+    ASSERT_ON_STACK_GUARD();
+
     if (display && getHwComposer().isConnected(*display->getId()) && !display->isPoweredOn()) {
         return;
     }
 
     nsecs_t currentTime = systemTime();
+    DEFINE_STACK_GUARD(currentTime);
     if (mHasPoweredOff) {
         mHasPoweredOff = false;
     } else {
         nsecs_t elapsedTime = currentTime - getBE().mLastSwapTime;
+        DEFINE_STACK_GUARD(elapsedTime);
         size_t numPeriods = static_cast<size_t>(elapsedTime / stats.vsyncPeriod);
+        DEFINE_STACK_GUARD(numPeriods);
         if (numPeriods < SurfaceFlingerBE::NUM_BUCKETS - 1) {
             getBE().mFrameBuckets[numPeriods] += elapsedTime;
         } else {
             getBE().mFrameBuckets[SurfaceFlingerBE::NUM_BUCKETS - 1] += elapsedTime;
         }
         getBE().mTotalTime += elapsedTime;
+
+        ASSERT_ON_STACK_GUARD();
     }
     getBE().mLastSwapTime = currentTime;
+    ASSERT_ON_STACK_GUARD();
 
     {
         std::lock_guard lock(mTexturePoolMutex);
+        DEFINE_STACK_GUARD(lock);
         const size_t refillCount = mTexturePoolSize - mTexturePool.size();
+        DEFINE_STACK_GUARD(refillCount);
         if (refillCount > 0) {
             const size_t offset = mTexturePool.size();
             mTexturePool.resize(mTexturePoolSize);
             getRenderEngine().genTextures(refillCount, mTexturePool.data() + offset);
             ATRACE_INT("TexturePoolSize", mTexturePool.size());
         }
+        ASSERT_ON_STACK_GUARD();
     }
 
     mTransactionCompletedThread.addPresentFence(mPreviousPresentFence);
     mTransactionCompletedThread.sendCallbacks();
+
+    ASSERT_ON_STACK_GUARD();
 }
+#pragma clang optimize on // b/119477596
 
 void SurfaceFlinger::rebuildLayerStacks() {
     ATRACE_CALL();