diff options
author | Elliott Hughes <enh@google.com> | 2011-06-07 16:39:20 -0700 |
---|---|---|
committer | Elliott Hughes <enh@google.com> | 2011-06-07 16:39:20 -0700 |
commit | 708f143f318bb2167c810f9506102f4ad656545c (patch) | |
tree | 97e9b578ea7175f56a335cad1548bbf4ef0d0fbb /vm/Misc.cpp | |
parent | a0f945f21dd38df48946fcea57d798a9692734b8 (diff) | |
download | android_dalvik-708f143f318bb2167c810f9506102f4ad656545c.tar.gz android_dalvik-708f143f318bb2167c810f9506102f4ad656545c.tar.bz2 android_dalvik-708f143f318bb2167c810f9506102f4ad656545c.zip |
Improve "waiting on"/"waiting to lock" SIGQUIT dump info.
In particular, when we're waiting on a Class, say which class:
I(16573) - waiting on <0xf5ed54f8> (java.lang.Class<java.lang.ref.ReferenceQueue>)
versus:
I(16573) - waiting on <0xf5feda38> (a java.util.LinkedList)
Bug: http://code.google.com/p/android/issues/detail?id=17349
Change-Id: I844d02c008b1499adb02995ff3da25ba8cad0e0a
Diffstat (limited to 'vm/Misc.cpp')
-rw-r--r-- | vm/Misc.cpp | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/vm/Misc.cpp b/vm/Misc.cpp index 627c4e2ec..3b1179e44 100644 --- a/vm/Misc.cpp +++ b/vm/Misc.cpp @@ -715,3 +715,58 @@ const char* dvmPathToAbsolutePortion(const char* path) { return NULL; } + +// From RE2. +static void StringAppendV(std::string* dst, const char* format, va_list ap) { + // First try with a small fixed size buffer + char space[1024]; + + // It's possible for methods that use a va_list to invalidate + // the data in it upon use. The fix is to make a copy + // of the structure before using it and use that copy instead. + va_list backup_ap; + va_copy(backup_ap, ap); + int result = vsnprintf(space, sizeof(space), format, backup_ap); + va_end(backup_ap); + + if ((result >= 0) && ((size_t) result < sizeof(space))) { + // It fit + dst->append(space, result); + return; + } + + // Repeatedly increase buffer size until it fits + int length = sizeof(space); + while (true) { + if (result < 0) { + // Older behavior: just try doubling the buffer size + length *= 2; + } else { + // We need exactly "result+1" characters + length = result+1; + } + char* buf = new char[length]; + + // Restore the va_list before we use it again + va_copy(backup_ap, ap); + result = vsnprintf(buf, length, format, backup_ap); + va_end(backup_ap); + + if ((result >= 0) && (result < length)) { + // It fit + dst->append(buf, result); + delete[] buf; + return; + } + delete[] buf; + } +} + +std::string dvmStringPrintf(const char* fmt, ...) { + va_list ap; + va_start(ap, fmt); + std::string result; + StringAppendV(&result, fmt, ap); + va_end(ap); + return result; +} |