Add handler for printing java stack traces for compiled code SIGSEGV.

Added a new FaultHandler which attempts to print a java stack trace
when a SIGSEGV occurse in generated code. This should help debugging
compiler and GC related heap corruption.

Bug: 13725693
Bug: 12934910

Change-Id: Id54d83ea180c222eb86d449c61926e83f0b026ad
diff --git a/runtime/arch/arm/fault_handler_arm.cc b/runtime/arch/arm/fault_handler_arm.cc
index 65a4952..aaba598 100644
--- a/runtime/arch/arm/fault_handler_arm.cc
+++ b/runtime/arch/arm/fault_handler_arm.cc
@@ -45,12 +45,13 @@
   return instr_size;
 }
 
-void FaultManager::GetMethodAndReturnPC(void* context, uintptr_t& method, uintptr_t& return_pc) {
+void FaultManager::GetMethodAndReturnPCAndSP(void* context, mirror::ArtMethod** out_method,
+                                             uintptr_t* out_return_pc, uintptr_t* out_sp) {
   struct ucontext *uc = (struct ucontext *)context;
   struct sigcontext *sc = reinterpret_cast<struct sigcontext*>(&uc->uc_mcontext);
-  uintptr_t* sp = reinterpret_cast<uint32_t*>(sc->arm_sp);
-  LOG(DEBUG) << "sp: " << sp;
-  if (sp == nullptr) {
+  *out_sp = static_cast<uintptr_t>(sc->arm_sp);
+  LOG(DEBUG) << "sp: " << *out_sp;
+  if (*out_sp == 0) {
     return;
   }
 
@@ -58,12 +59,12 @@
   // get the method from the top of the stack.  However it's in r0.
   uintptr_t* fault_addr = reinterpret_cast<uintptr_t*>(sc->fault_address);
   uintptr_t* overflow_addr = reinterpret_cast<uintptr_t*>(
-      reinterpret_cast<uint8_t*>(sp) - Thread::kStackOverflowReservedBytes);
+      reinterpret_cast<uint8_t*>(*out_sp) - Thread::kStackOverflowReservedBytes);
   if (overflow_addr == fault_addr) {
-    method = sc->arm_r0;
+    *out_method = reinterpret_cast<mirror::ArtMethod*>(sc->arm_r0);
   } else {
     // The method is at the top of the stack.
-    method = sp[0];
+    *out_method = reinterpret_cast<mirror::ArtMethod*>(reinterpret_cast<uintptr_t*>(*out_sp)[0]);
   }
 
   // Work out the return PC.  This will be the address of the instruction
@@ -76,7 +77,7 @@
   LOG(DEBUG) << "pc: " << std::hex << static_cast<void*>(ptr);
   uint32_t instr_size = GetInstructionSize(ptr);
 
-  return_pc = (sc->arm_pc + instr_size) | 1;
+  *out_return_pc = (sc->arm_pc + instr_size) | 1;
 }
 
 bool NullPointerHandler::Action(int sig, siginfo_t* info, void* context) {
@@ -87,7 +88,7 @@
   // register in order to find the mapping.
 
   // Need to work out the size of the instruction that caused the exception.
-  struct ucontext *uc = (struct ucontext *)context;
+  struct ucontext *uc = reinterpret_cast<struct ucontext*>(context);
   struct sigcontext *sc = reinterpret_cast<struct sigcontext*>(&uc->uc_mcontext);
   uint8_t* ptr = reinterpret_cast<uint8_t*>(sc->arm_pc);