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
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index f17710e..7022c36 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -4695,6 +4695,12 @@
result.append("\n");
/*
+ * Tracing state
+ */
+ mTracing.dump(result);
+ result.append("\n");
+
+ /*
* HWC layer minidump
*/
for (const auto& [token, display] : mDisplays) {
@@ -5083,12 +5089,12 @@
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);
}
diff --git a/services/surfaceflinger/SurfaceTracing.cpp b/services/surfaceflinger/SurfaceTracing.cpp
index 0e9b04e..370b3b8 100644
--- a/services/surfaceflinger/SurfaceTracing.cpp
+++ b/services/surfaceflinger/SurfaceTracing.cpp
@@ -52,7 +52,7 @@
return err;
}
-bool SurfaceTracing::isEnabled() {
+bool SurfaceTracing::isEnabled() const {
return mEnabled;
}
@@ -65,6 +65,15 @@
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 @@
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
diff --git a/services/surfaceflinger/SurfaceTracing.h b/services/surfaceflinger/SurfaceTracing.h
index 590ab96..27e2c9e 100644
--- a/services/surfaceflinger/SurfaceTracing.h
+++ b/services/surfaceflinger/SurfaceTracing.h
@@ -18,6 +18,7 @@
#include <layerproto/LayerProtoHeader.h>
#include <utils/Errors.h>
+#include <utils/String8.h>
#include <mutex>
@@ -32,9 +33,10 @@
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 @@
bool mEnabled = false;
std::string mOutputFileName = DEFAULT_FILENAME;
- std::mutex mTraceMutex;
+ mutable std::mutex mTraceMutex;
LayersTraceFileProto mTrace;
};