envsetup.sh: add functions to enable and generate core dumps

The shell functions in this patch enable crashing processes with the core limit
set correctly to dump core in directory /cores.  They do so by remounting the
root partition, which is RAM-backed, and by creating the 0777-chmodded /cores
under it. They also set the core file pattern in /proc/sys/kernel/core_pattern
to be /cores/core.%p, such that a core dump will have the crashing process' PID
appended to it.  You enable core-dump generation once per boot, as follows:

	coredump-setup

If a process does not have its core-size rlimit set (as most do not), you can
either set it manually by typing "adb shell prlimit <pid> 4 -1 -1", or by
typing coredump-enable <name>, e.g.

	coredump-enable $(pid mediaserver)

Alternatively, you can cause a running process to dump core by sending it a
SIGSEGV via the shell function core <name>, e.g.:

	core $(pid mediaserver)

Change-Id: Ib174e7ee95515fb9866fa6bf0d5b5bf23f3ec61b
Signed-off-by: Iliyan Malchev <malchev@google.com>
diff --git a/envsetup.sh b/envsetup.sh
index f4c6566..2ed12c9 100644
--- a/envsetup.sh
+++ b/envsetup.sh
@@ -890,6 +890,84 @@
     fi
 }
 
+# coredump-setup - enable core dumps globally for any process
+#                  that has the core-file-size limit set correctly
+#
+# NOTE: You must call also coredump-enable for a specific process
+#       if its core-file-size limit is not set already.
+# NOTE: Core dumps are written to ramdisk; they will not survive a reboot!
+
+function coredump-setup()
+{
+	echo "Getting root...";
+	adb root;
+	adb wait-for-device;
+
+	echo "Remounting root parition read-write...";
+	adb shell mount -w -o remount -t rootfs rootfs;
+	sleep 1;
+	adb wait-for-device;
+	adb shell mkdir -p /cores;
+	adb shell chmod 0777 /cores;
+
+	echo "Granting SELinux permission to dump in /cores...";
+	adb shell restorecon -R /cores;
+
+	echo "Set core pattern.";
+	adb shell 'echo /cores/core.%p > /proc/sys/kernel/core_pattern';
+
+	echo "Done."
+}
+
+# coredump-enable - enable core dumps for the specified process
+# $1 = PID of process (e.g., $(pid mediaserver))
+#
+# NOTE: coredump-setup must have been called as well for a core
+#       dump to actually be generated.
+
+function coredump-enable()
+{
+	local PID=$1;
+	if [ -z "$PID" ]; then
+		printf "Expecting a PID!\n";
+		return;
+	fi;
+	echo "Setting core limit for $PID to infinite...";
+	adb shell prlimit $PID 4 -1 -1
+}
+
+# core - send SIGV and pull the core for process
+# $1 = PID of process (e.g., $(pid mediaserver))
+#
+# NOTE: coredump-setup must be called once per boot for core dumps to be
+#       enabled globally.
+
+function core()
+{
+	local PID=$1;
+
+	if [ -z "$PID" ]; then
+		printf "Expecting a PID!\n";
+		return;
+	fi;
+
+	local CORENAME=core.$PID;
+	local COREPATH=/cores/$CORENAME;
+	local SIG=SEGV;
+
+	coredump-enable $1;
+
+	local done=0;
+	while [ $(adb shell "[ -d /proc/$PID ] && echo -n yes") ]; do
+		printf "\tSending SIG%s to %d...\n" $SIG $PID;
+		adb shell kill -$SIG $PID;
+		sleep 1;
+	done;
+
+	adb shell "while [ ! -f $COREPATH ] ; do echo waiting for $COREPATH to be generated; sleep 1; done"
+	echo "Done: core is under $COREPATH on device.";
+}
+
 # systemstack - dump the current stack trace of all threads in the system process
 # to the usual ANR traces file
 function systemstack()