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

Commit adc69617 authored by Yichi Chen's avatar Yichi Chen
Browse files

SF: Enforce a size limitation on SurfaceTracing

SurfaceTracing records operations of each frame update. It can exhaust
more than 2GB on memory heap in 5 mins if display keeps updating.
Enforce a size limitation on it and stop automatically to prevent memory
and stroage from exhausting.

Bug: b/115434782
Test: adb shell service call SurfaceFlinger 1025 i32 1
Result: SurfaceTracing can be disabled after running for a while.

Change-Id: I52d945f86a7bc501590b7c311f63a6273b9192fd
parent 84ae607b
Loading
Loading
Loading
Loading
+8 −2
Original line number Diff line number Diff line
@@ -4694,6 +4694,12 @@ void SurfaceFlinger::dumpAllLocked(const Vector<String16>& args, size_t& index,
    }
    result.append("\n");

    /*
     * Tracing state
     */
    mTracing.dump(result);
    result.append("\n");

    /*
     * HWC layer minidump
     */
@@ -5083,12 +5089,12 @@ status_t SurfaceFlinger::onTransact(uint32_t code, const Parcel& data, Parcel* r
            case 1025: { // Set layer tracing
                n = data.readInt32();
                if (n) {
                    ALOGV("LayerTracing enabled");
                    ALOGD("LayerTracing enabled");
                    mTracing.enable();
                    doTracing("tracing.enable");
                    reply->writeInt32(NO_ERROR);
                } else {
                    ALOGV("LayerTracing disabled");
                    ALOGD("LayerTracing disabled");
                    status_t err = mTracing.disable();
                    reply->writeInt32(err);
                }
+17 −1
Original line number Diff line number Diff line
@@ -52,7 +52,7 @@ status_t SurfaceTracing::disable() {
    return err;
}

bool SurfaceTracing::isEnabled() {
bool SurfaceTracing::isEnabled() const {
    return mEnabled;
}

@@ -65,6 +65,15 @@ void SurfaceTracing::traceLayers(const char* where, LayersProto layers) {
    entry->set_elapsed_realtime_nanos(elapsedRealtimeNano());
    entry->set_where(where);
    entry->mutable_layers()->Swap(&layers);

    constexpr int maxBufferedEntryCount = 3600;
    if (mTrace.entry_size() >= maxBufferedEntryCount) {
        // TODO: flush buffered entries without disabling tracing
        ALOGE("too many buffered frames; force disable tracing");
        mEnabled = false;
        writeProtoFileLocked();
        mTrace.Clear();
    }
}

status_t SurfaceTracing::writeProtoFileLocked() {
@@ -84,4 +93,11 @@ status_t SurfaceTracing::writeProtoFileLocked() {
    return NO_ERROR;
}

void SurfaceTracing::dump(String8& result) const {
    std::lock_guard<std::mutex> protoGuard(mTraceMutex);

    result.appendFormat("Tracing state: %s\n", mEnabled ? "enabled" : "disabled");
    result.appendFormat("  number of entries: %d\n", mTrace.entry_size());
}

} // namespace android
+4 −2
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@

#include <layerproto/LayerProtoHeader.h>
#include <utils/Errors.h>
#include <utils/String8.h>

#include <mutex>

@@ -32,9 +33,10 @@ class SurfaceTracing {
public:
    void enable();
    status_t disable();
    bool isEnabled();
    bool isEnabled() const;

    void traceLayers(const char* where, LayersProto);
    void dump(String8& result) const;

private:
    static constexpr auto DEFAULT_FILENAME = "/data/misc/wmtrace/layers_trace.pb";
@@ -43,7 +45,7 @@ private:

    bool mEnabled = false;
    std::string mOutputFileName = DEFAULT_FILENAME;
    std::mutex mTraceMutex;
    mutable std::mutex mTraceMutex;
    LayersTraceFileProto mTrace;
};