From 78da0d7e968d96e432c449d7f471e9f59014eb76 Mon Sep 17 00:00:00 2001 From: Andreas Gampe Date: Mon, 5 Sep 2016 12:30:49 -0700 Subject: [PATCH] ART: Dump more info on 137-cfi failure Print the maps of the secondary process. Try to induce in-process dumping of the secondary. Bug: 31208203 Change-Id: I16a80e8510b297d61a51fdee91ab1c2f2e5a47c8 --- test/137-cfi/cfi.cc | 26 +++++++++++++++++++++++++- test/137-cfi/src/Main.java | 23 ++++++++++++++++++++++- 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/test/137-cfi/cfi.cc b/test/137-cfi/cfi.cc index 45251b8f7..9f1499e38 100644 --- a/test/137-cfi/cfi.cc +++ b/test/137-cfi/cfi.cc @@ -29,6 +29,7 @@ #include "base/logging.h" #include "base/macros.h" +#include "base/stringprintf.h" #include "gc/heap.h" #include "gc/space/image_space.h" #include "oat_file.h" @@ -55,7 +56,7 @@ extern "C" JNIEXPORT jboolean JNICALL Java_Main_sleep(JNIEnv*, jobject, jint, jb // Keep pausing. printf("Going to sleep\n"); for (;;) { - pause(); + sleep(1); } } @@ -86,6 +87,19 @@ static bool CheckStack(Backtrace* bt, const std::vector& seq) { return false; } + +static void MoreErrorInfo(pid_t pid, bool sig_quit_on_fail) { + printf("Secondary pid is %d\n", pid); + + PrintFileToLog(StringPrintf("/proc/%d/maps", pid), ERROR); + + if (sig_quit_on_fail) { + int res = kill(pid, SIGQUIT); + if (res != 0) { + PLOG(ERROR) << "Failed to send signal"; + } + } +} #endif // Currently we have to fall back to our own loader for the boot image when it's compiled PIC @@ -254,10 +268,20 @@ extern "C" JNIEXPORT jboolean JNICALL Java_Main_unwindOtherProcess( result = CheckStack(bt.get(), full_signatrues ? full_seq : seq); } + constexpr bool kSigQuitOnFail = true; + if (!result) { + MoreErrorInfo(pid, kSigQuitOnFail); + } + if (ptrace(PTRACE_DETACH, pid, 0, 0) != 0) { PLOG(ERROR) << "Detach failed"; } + // If we failed to unwind and induced an ANR dump, give the child some time (20s). + if (!result && kSigQuitOnFail) { + sleep(20); + } + // Kill the other process once we are done with it. kill(pid, SIGKILL); diff --git a/test/137-cfi/src/Main.java b/test/137-cfi/src/Main.java index 5cfe33dc5..1ec70722b 100644 --- a/test/137-cfi/src/Main.java +++ b/test/137-cfi/src/Main.java @@ -101,9 +101,10 @@ public class Main implements Comparator
{ } // Wait until the forked process had time to run until its sleep phase. + BufferedReader lineReader; try { InputStreamReader stdout = new InputStreamReader(p.getInputStream(), "UTF-8"); - BufferedReader lineReader = new BufferedReader(stdout); + lineReader = new BufferedReader(stdout); while (!lineReader.readLine().contains("Going to sleep")) { } } catch (Exception e) { @@ -112,6 +113,26 @@ public class Main implements Comparator
{ if (!unwindOtherProcess(fullSignatures, pid)) { System.out.println("Unwinding other process failed."); + + // In this case, log all the output. + // Note: this is potentially non-terminating code, if the secondary is totally stuck. + // We rely on the run-test timeout infrastructure to terminate the primary in + // such a case. + try { + String tmp; + System.out.println("Output from the secondary:"); + while ((tmp = lineReader.readLine()) != null) { + System.out.println("Secondary: " + tmp); + } + } catch (Exception e) { + e.printStackTrace(System.out); + } + } + + try { + lineReader.close(); + } catch (Exception e) { + e.printStackTrace(System.out); } } finally { // Kill the forked process if it is not already dead. -- 2.11.0