summaryrefslogtreecommitdiffstats
path: root/vm
diff options
context:
space:
mode:
authorBiswajit Paul <biswajitpaul@codeaurora.org>2013-04-05 14:52:42 +0530
committerLinux Build Service Account <lnxbuild@localhost>2013-10-31 19:37:41 -0600
commite17852495a15ddad079305c725d067ac95e4d655 (patch)
treec7949bf531d660dd867c3b0ff213cbb605cb5186 /vm
parent8a3d69efa6fff89f5e83fccbdb657fd530822f0f (diff)
downloadandroid_dalvik-e17852495a15ddad079305c725d067ac95e4d655.tar.gz
android_dalvik-e17852495a15ddad079305c725d067ac95e4d655.tar.bz2
android_dalvik-e17852495a15ddad079305c725d067ac95e4d655.zip
Dump hprof when app encounters Out of memory
These changes will only dump application hprof when debug property "dalvik.debug.oom" is set to -1. CRs-Fixed: 471156 Change-Id: I41fbbd5cdaa852cd5e8896186e9d3993688a9cb0 (cherry picked from commit eac7514a989e78b191fde100475b907427158b8d) (cherry picked from commit 63a1141f9bb9fc58beacdde1e8e24df82fe6e000)
Diffstat (limited to 'vm')
-rw-r--r--vm/alloc/Heap.cpp57
1 files changed, 52 insertions, 5 deletions
diff --git a/vm/alloc/Heap.cpp b/vm/alloc/Heap.cpp
index 2de20ef0c..f9e6d793a 100644
--- a/vm/alloc/Heap.cpp
+++ b/vm/alloc/Heap.cpp
@@ -28,14 +28,18 @@
#include "alloc/HeapSource.h"
#include "alloc/MarkSweep.h"
#include "os/os.h"
-
#include <sys/mman.h>
+#include "hprof/Hprof.h"
#include <sys/resource.h>
#include <sys/time.h>
#include <limits.h>
#include <errno.h>
-
#include <cutils/trace.h>
+#include <cutils/process_name.h>
+
+#ifdef HAVE_ANDROID_OS
+#include "cutils/properties.h"
+#endif
static const GcSpec kGcForMallocSpec = {
true, /* isPartial */
@@ -183,8 +187,13 @@ static void gcForMalloc(bool clearSoftReferences)
*/
static void *tryMalloc(size_t size)
{
+#ifdef HAVE_ANDROID_OS
+ char prop_value[PROPERTY_VALUE_MAX] = {'\0'};
+#endif
+ char* hprof_file = NULL;
void *ptr;
-
+ int result = -1;
+ int debug_oom = 0;
//TODO: figure out better heuristics
// There will be a lot of churn if someone allocates a bunch of
// big objects in a row, and we hit the frag case each time.
@@ -199,7 +208,6 @@ static void *tryMalloc(size_t size)
if (ptr != NULL) {
return ptr;
}
-
/*
* The allocation failed. If the GC is running, block until it
* completes and retry.
@@ -238,7 +246,6 @@ static void *tryMalloc(size_t size)
FRACTIONAL_MB(newHeapSize), size);
return ptr;
}
-
/* Most allocations should have succeeded by now, so the heap
* is really full, really fragmented, or the requested size is
* really big. Do another GC, collecting SoftReferences this
@@ -259,6 +266,46 @@ static void *tryMalloc(size_t size)
//TODO: tell the HeapSource to dump its state
dvmDumpThread(dvmThreadSelf(), false);
+#ifdef HAVE_ANDROID_OS
+ /* Read the property to check whether hprof should be generated or not */
+ property_get("dalvik.debug.oom",prop_value,"0");
+ debug_oom = atoi(prop_value);
+#endif
+ if(debug_oom == 1) {
+ LOGE_HEAP("Generating hprof for process: %s PID: %d",
+ get_process_name(),getpid());
+ dvmUnlockHeap();
+
+ /* allocate memory for hprof file name. Allocate approx 30 bytes.
+ * 11 byte for directory path, 10 bytes for pid, 6 bytes for
+ * extension + "\0'.
+ */
+ hprof_file = (char*) malloc (sizeof(char) * 30);
+
+ /* creation of hprof will fail if /data/misc permission is not set
+ * to 0777.
+ */
+
+ if(hprof_file) {
+ snprintf(hprof_file,30,"/data/misc/%d.hprof",getpid());
+ LOGE_HEAP("Generating hprof in file: %s",hprof_file );
+
+ result = hprofDumpHeap(hprof_file, -1, false);
+ free(hprof_file);
+ } else {
+ LOGE_HEAP("Failed to allocate memory for file name."
+ "Generating hprof in default file: /data/misc/app_oom.hprof");
+ result = hprofDumpHeap("/data/misc/app_oom.hprof", -1, false);
+ }
+ dvmLockMutex(&gDvm.gcHeapLock);
+
+ if (result != 0) {
+ /* ideally we'd throw something more specific based on actual failure */
+ dvmThrowRuntimeException(
+ "Failure during heap dump; check log output for details");
+ LOGE_HEAP(" hprofDumpHeap failed with result: %d ",result);
+ }
+ }
return NULL;
}