summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Cheng <bccheng@android.com>2011-10-10 16:26:36 -0700
committerBen Cheng <bccheng@android.com>2011-10-10 16:26:36 -0700
commitf7c18055de6e7ffb3ee16a45680ea0ffd6158fbd (patch)
tree9b564ad9b5f50a0437289ecdeb00e5d7225bbc14
parentc2fdadcdfc8fd249f646153457f5cffde54d7945 (diff)
downloadandroid_dalvik-f7c18055de6e7ffb3ee16a45680ea0ffd6158fbd.tar.gz
android_dalvik-f7c18055de6e7ffb3ee16a45680ea0ffd6158fbd.tar.bz2
android_dalvik-f7c18055de6e7ffb3ee16a45680ea0ffd6158fbd.zip
Leave up to 512 chars of gDvm.lastMessage on dvmAbort's stack frame.
Bug: 5372634 Change-Id: I019a059e5a989de3dfc9e2f5e78f7caa7168cf75
-rw-r--r--vm/Globals.h3
-rw-r--r--vm/Init.cpp39
-rw-r--r--vm/oo/Class.cpp1
3 files changed, 42 insertions, 1 deletions
diff --git a/vm/Globals.h b/vm/Globals.h
index 397bfea85..3cc0b49e2 100644
--- a/vm/Globals.h
+++ b/vm/Globals.h
@@ -722,6 +722,9 @@ struct DvmGlobals {
#ifdef VERIFIER_STATS
VerifierStats verifierStats;
#endif
+
+ /* String pointed here will be deposited on the stack frame of dvmAbort */
+ const char *lastMessage;
};
extern struct DvmGlobals gDvm;
diff --git a/vm/Init.cpp b/vm/Init.cpp
index 404a63d19..36ac2692e 100644
--- a/vm/Init.cpp
+++ b/vm/Init.cpp
@@ -1791,6 +1791,43 @@ void dvmPrintNativeBackTrace() {
*/
void dvmAbort()
{
+ /*
+ * Leave gDvm.lastMessage on the stack frame which can be decoded in the
+ * tombstone file. This is for situations where we only have tombstone files
+ * but no logs (ie b/5372634).
+ *
+ * For example, in the tombstone file you usually see this:
+ *
+ * #00 pc 00050ef2 /system/lib/libdvm.so (dvmAbort)
+ * #01 pc 00077670 /system/lib/libdvm.so (_Z15dvmClassStartupv)
+ * :
+ *
+ * stack:
+ * :
+ * #00 beed2658 00000000
+ * beed265c 7379732f
+ * beed2660 2f6d6574
+ * beed2664 6d617266
+ * beed2668 726f7765
+ * beed266c 6f632f6b
+ * beed2670 6a2e6572
+ * beed2674 00007261
+ * beed2678 00000000
+ *
+ * The ascii values between beed265c and beed2674 belongs to messageBuffer
+ * and it can be decoded as "/system/framework/core.jar".
+ */
+ const int messageLength = 512;
+ char messageBuffer[messageLength] = {0};
+ int result = 0;
+
+ snprintf(messageBuffer, messageLength, "%s", gDvm.lastMessage);
+
+ /* So that messageBuffer[] looks like useful stuff to the compiler */
+ for (int i = 0; i < messageLength && messageBuffer[i]; i++) {
+ result += messageBuffer[i];
+ }
+
LOGE("VM aborting");
fflush(NULL); // flush all open file buffers
@@ -1815,7 +1852,7 @@ void dvmAbort()
* We can also trivially tell the difference between a VM crash and
* a deliberate abort by looking at the fault address.
*/
- *((char*)0xdeadd00d) = 38;
+ *((char*)0xdeadd00d) = result;
abort();
/* notreached */
diff --git a/vm/oo/Class.cpp b/vm/oo/Class.cpp
index bc331030c..85a3bbd15 100644
--- a/vm/oo/Class.cpp
+++ b/vm/oo/Class.cpp
@@ -738,6 +738,7 @@ static ClassPathEntry* processClassPath(const char* pathStr, bool isBootstrap)
* case, so just bail out (reasonably) gracefully.
*/
LOGE("No valid entries found in bootclasspath '%s'", pathStr);
+ gDvm.lastMessage = pathStr;
dvmAbort();
}