ART: Change the stack dump format to be in line with debuggerd

Make offsets 16 digits on 64-bit platforms.

Add the ability to provide the build fingerprint, and print it in
the traces output.

Bug: 22693991

(cherry picked from commit 242ae94dc39be53e519a6163ea1db494ceb75954)

Change-Id: Ibd3d3b3bd65dce84acfb97a487807d6f280a9508
diff --git a/runtime/parsed_options.cc b/runtime/parsed_options.cc
index 7772354..25b5e49 100644
--- a/runtime/parsed_options.cc
+++ b/runtime/parsed_options.cc
@@ -263,6 +263,9 @@
       .Define("--cpu-abilist=_")
           .WithType<std::string>()
           .IntoKey(M::CpuAbiList)
+      .Define("-Xfingerprint:_")
+          .WithType<std::string>()
+          .IntoKey(M::Fingerprint)
       .Define({"-Xexperimental-lambdas", "-Xnoexperimental-lambdas"})
           .WithType<bool>()
           .WithValues({true, false})
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index c92f08f..a297510 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -852,6 +852,8 @@
 
   Split(runtime_options.GetOrDefault(Opt::CpuAbiList), ',', &cpu_abilist_);
 
+  fingerprint_ = runtime_options.ReleaseOrDefault(Opt::Fingerprint);
+
   if (runtime_options.GetOrDefault(Opt::Interpret)) {
     GetInstrumentation()->ForceInterpretOnly();
   }
diff --git a/runtime/runtime.h b/runtime/runtime.h
index 8aed768..4577b75 100644
--- a/runtime/runtime.h
+++ b/runtime/runtime.h
@@ -563,6 +563,11 @@
 
   bool IsDebuggable() const;
 
+  // Returns the build fingerprint, if set. Otherwise an empty string is returned.
+  std::string GetFingerprint() {
+    return fingerprint_;
+  }
+
  private:
   static void InitPlatformSignalHandlers();
 
@@ -757,6 +762,9 @@
 
   MethodRefToStringInitRegMap method_ref_string_init_reg_map_;
 
+  // Contains the build fingerprint, if given as a parameter.
+  std::string fingerprint_;
+
   DISALLOW_COPY_AND_ASSIGN(Runtime);
 };
 std::ostream& operator<<(std::ostream& os, const Runtime::CalleeSaveType& rhs);
diff --git a/runtime/runtime_options.def b/runtime/runtime_options.def
index 9922c5f..02ed3a2 100644
--- a/runtime/runtime_options.def
+++ b/runtime/runtime_options.def
@@ -112,6 +112,7 @@
 RUNTIME_OPTIONS_KEY (unsigned int,        ZygoteMaxFailedBoots,           10)
 RUNTIME_OPTIONS_KEY (Unit,                NoDexFileFallback)
 RUNTIME_OPTIONS_KEY (std::string,         CpuAbiList)
+RUNTIME_OPTIONS_KEY (std::string,         Fingerprint)
 RUNTIME_OPTIONS_KEY (bool,                ExperimentalLambdas,            false) // -X[no]experimental-lambdas
 
 // Not parse-able from command line, but can be provided explicitly.
diff --git a/runtime/signal_catcher.cc b/runtime/signal_catcher.cc
index 9f8c55c..6cb7950 100644
--- a/runtime/signal_catcher.cc
+++ b/runtime/signal_catcher.cc
@@ -133,8 +133,11 @@
 
   DumpCmdLine(os);
 
-  // Note: The string "ABI:" is chosen to match the format used by debuggerd.
-  os << "ABI: " << GetInstructionSetString(runtime->GetInstructionSet()) << "\n";
+  // Note: The strings "Build fingerprint:" and "ABI:" are chosen to match the format used by
+  // debuggerd. This allows, for example, the stack tool to work.
+  std::string fingerprint = runtime->GetFingerprint();
+  os << "Build fingerprint: '" << (fingerprint.empty() ? "unknown" : fingerprint) << "'\n";
+  os << "ABI: '" << GetInstructionSetString(runtime->GetInstructionSet()) << "'\n";
 
   os << "Build type: " << (kIsDebugBuild ? "debug" : "optimized") << "\n";
 
diff --git a/runtime/utils.cc b/runtime/utils.cc
index 194d9fe..20512f9 100644
--- a/runtime/utils.cc
+++ b/runtime/utils.cc
@@ -1130,9 +1130,13 @@
     os << prefix << StringPrintf("#%02zu pc ", it->num);
     bool try_addr2line = false;
     if (!BacktraceMap::IsValid(it->map)) {
-      os << StringPrintf("%08" PRIxPTR "  ???", it->pc);
+      os << StringPrintf(Is64BitInstructionSet(kRuntimeISA) ? "%016" PRIxPTR "  ???"
+                                                            : "%08" PRIxPTR "  ???",
+                         it->pc);
     } else {
-      os << StringPrintf("%08" PRIxPTR "  ", BacktraceMap::GetRelativePc(it->map, it->pc));
+      os << StringPrintf(Is64BitInstructionSet(kRuntimeISA) ? "%016" PRIxPTR "  "
+                                                            : "%08" PRIxPTR "  ",
+                         BacktraceMap::GetRelativePc(it->map, it->pc));
       os << it->map.name;
       os << " (";
       if (!it->func_name.empty()) {