SurfaceFlinger: Add support for continuous dumpsys to file.
- Collect dumpsys to an outfile file when triggered. - Collect dumpsys before calling Prepare on hwc module in each draw cycle. Recollect dumpsys if Commit goes through successfully and replace former dumpsys with this. - Wrap around if file size reaches appx 20 MB. - Generate output file at /data/misc/display/dumpsys.txt - Syntax: adb shell dumpsys SurfaceFlinger --file [--no-limit] --file : Ouput dumpsys to file --no-limit : Do not wrap around, keep appending Use same command to trigger start and end of dumping. - Output format: | start code | after commit? | time stamp | dump size | dump data | CRs-Fixed: 947084 Change-Id: Ie520f51c69757aeec88b9400688a7f3271472349
This commit is contained in:
parent
0e898965c3
commit
a9cbaf5097
@ -39,6 +39,11 @@ LOCAL_SRC_FILES := \
|
||||
DisplayUtils.cpp
|
||||
|
||||
LOCAL_CFLAGS := -DLOG_TAG=\"SurfaceFlinger\"
|
||||
|
||||
ifeq ($(TARGET_BUILD_VARIANT),userdebug)
|
||||
LOCAL_CFLAGS += -DDEBUG_CONT_DUMPSYS
|
||||
endif
|
||||
|
||||
LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
|
||||
|
||||
ifeq ($(TARGET_BOARD_PLATFORM),omap4)
|
||||
|
@ -28,6 +28,7 @@
|
||||
|
||||
#include "ExSurfaceFlinger.h"
|
||||
#include "ExLayer.h"
|
||||
#include <fstream>
|
||||
#include <cutils/properties.h>
|
||||
#ifdef QTI_BSP
|
||||
#include <hardware/display_defs.h>
|
||||
@ -266,4 +267,110 @@ void ExSurfaceFlinger::drawWormHoleIfRequired(HWComposer::LayerListIterator& cur
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG_CONT_DUMPSYS
|
||||
status_t ExSurfaceFlinger::dump(int fd, const Vector<String16>& args) {
|
||||
// Format: adb shell dumpsys SurfaceFlinger --file --no-limit
|
||||
size_t numArgs = args.size();
|
||||
status_t err = NO_ERROR;
|
||||
|
||||
if (!numArgs || (args[0] != String16("--file"))) {
|
||||
return SurfaceFlinger::dump(fd, args);
|
||||
}
|
||||
|
||||
Mutex::Autolock _l(mFileDump.lock);
|
||||
|
||||
// Same command is used to start and end dump.
|
||||
mFileDump.running = !mFileDump.running;
|
||||
|
||||
if (mFileDump.running) {
|
||||
// Create an empty file or erase existing file.
|
||||
std::fstream fs;
|
||||
fs.open(mFileDump.name, std::ios::out);
|
||||
if (!fs) {
|
||||
mFileDump.running = false;
|
||||
err = UNKNOWN_ERROR;
|
||||
} else {
|
||||
mFileDump.position = 0;
|
||||
if (numArgs >= 2 && (args[1] == String16("--nolimit"))) {
|
||||
mFileDump.noLimit = true;
|
||||
} else {
|
||||
mFileDump.noLimit = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String8 result;
|
||||
result += mFileDump.running ? "Start" : "End";
|
||||
result += mFileDump.noLimit ? " unlimited" : " fixed limit";
|
||||
result += " dumpsys to file : ";
|
||||
result += mFileDump.name;
|
||||
result += "\n";
|
||||
|
||||
write(fd, result.string(), result.size());
|
||||
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
void ExSurfaceFlinger::dumpDrawCycle(bool prePrepare) {
|
||||
Mutex::Autolock _l(mFileDump.lock);
|
||||
|
||||
// User might stop dump collection in middle of prepare & commit.
|
||||
// Collect dumpsys again after commit and replace.
|
||||
if (!mFileDump.running && !mFileDump.replaceAfterCommit) {
|
||||
return;
|
||||
}
|
||||
|
||||
Vector<String16> args;
|
||||
size_t index = 0;
|
||||
String8 dumpsys;
|
||||
|
||||
dumpAllLocked(args, index, dumpsys);
|
||||
|
||||
char timeStamp[32];
|
||||
char dataSize[32];
|
||||
char hms[32];
|
||||
long millis;
|
||||
struct timeval tv;
|
||||
struct tm *ptm;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
ptm = localtime(&tv.tv_sec);
|
||||
strftime (hms, sizeof (hms), "%H:%M:%S", ptm);
|
||||
millis = tv.tv_usec / 1000;
|
||||
snprintf(timeStamp, sizeof(timeStamp), "Timestamp: %s.%03ld", hms, millis);
|
||||
snprintf(dataSize, sizeof(dataSize), "Size: %8zu", dumpsys.size());
|
||||
|
||||
std::fstream fs;
|
||||
fs.open(mFileDump.name, std::ios::in | std::ios::out);
|
||||
if (!fs) {
|
||||
ALOGE("Failed to open %s file for dumpsys", mFileDump.name);
|
||||
return;
|
||||
}
|
||||
|
||||
// Format:
|
||||
// | start code | after commit? | time stamp | dump size | dump data |
|
||||
fs.seekp(mFileDump.position, std::ios::beg);
|
||||
|
||||
fs << "#@#@-- DUMPSYS START --@#@#" << std::endl;
|
||||
fs << "PostCommit: " << ( prePrepare ? "false" : "true" ) << std::endl;
|
||||
fs << timeStamp << std::endl;
|
||||
fs << dataSize << std::endl;
|
||||
fs << dumpsys << std::endl;
|
||||
|
||||
if (prePrepare) {
|
||||
mFileDump.replaceAfterCommit = true;
|
||||
} else {
|
||||
mFileDump.replaceAfterCommit = false;
|
||||
// Reposition only after commit.
|
||||
// Keem file size to appx 20 MB limit by default, wrap around if exceeds.
|
||||
mFileDump.position = fs.tellp();
|
||||
if (!mFileDump.noLimit && (mFileDump.position > (20 * 1024 * 1024))) {
|
||||
mFileDump.position = 0;
|
||||
}
|
||||
}
|
||||
|
||||
fs.close();
|
||||
}
|
||||
#endif
|
||||
|
||||
}; // namespace android
|
||||
|
@ -79,6 +79,20 @@ protected:
|
||||
bool mDebugLogs;
|
||||
bool isDebug() { return mDebugLogs; }
|
||||
bool mDisableExtAnimation;
|
||||
|
||||
#ifdef DEBUG_CONT_DUMPSYS
|
||||
virtual status_t dump(int fd, const Vector<String16>& args);
|
||||
virtual void dumpDrawCycle(bool prePrepare );
|
||||
|
||||
struct {
|
||||
Mutex lock;
|
||||
const char *name = "/data/misc/display/dumpsys.txt";
|
||||
bool running = false;
|
||||
bool noLimit = false;
|
||||
bool replaceAfterCommit = false;
|
||||
long int position = 0;
|
||||
} mFileDump;
|
||||
#endif
|
||||
};
|
||||
|
||||
}; //namespace android
|
||||
|
@ -1081,6 +1081,8 @@ void SurfaceFlinger::postComposition()
|
||||
mAnimFrameTracker.advanceFrame();
|
||||
}
|
||||
|
||||
dumpDrawCycle(false);
|
||||
|
||||
if (hw->getPowerMode() == HWC_POWER_MODE_OFF) {
|
||||
return;
|
||||
}
|
||||
@ -1248,6 +1250,8 @@ void SurfaceFlinger::setUpHWComposer() {
|
||||
}
|
||||
}
|
||||
|
||||
dumpDrawCycle(true);
|
||||
|
||||
status_t err = hwc.prepare();
|
||||
ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
|
||||
|
||||
|
@ -471,6 +471,7 @@ private:
|
||||
void logFrameStats();
|
||||
|
||||
void dumpStaticScreenStats(String8& result) const;
|
||||
virtual void dumpDrawCycle(bool /* prePrepare */ ) { }
|
||||
|
||||
/* ------------------------------------------------------------------------
|
||||
* Attributes
|
||||
|
Loading…
Reference in New Issue
Block a user