diff options
| -rw-r--r-- | runtime/runtime.cc | 8 | ||||
| -rwxr-xr-x | test/etc/run-test-jar | 63 |
2 files changed, 59 insertions, 12 deletions
diff --git a/runtime/runtime.cc b/runtime/runtime.cc index 49451ade94..431ba95c13 100644 --- a/runtime/runtime.cc +++ b/runtime/runtime.cc @@ -20,6 +20,7 @@ #include <sys/mount.h> #ifdef __linux__ #include <linux/fs.h> +#include <sys/prctl.h> #endif #define ATRACE_TAG ATRACE_TAG_DALVIK @@ -492,6 +493,13 @@ bool Runtime::Start() { CHECK(!no_sig_chain_) << "A started runtime should have sig chain enabled"; + // If a debug host build, disable ptrace restriction for debugging and test timeout thread dump. +#if defined(__linux__) && !defined(__ANDROID__) + if (kIsDebugBuild) { + CHECK_EQ(prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY), 0); + } +#endif + // Restore main thread state to kNative as expected by native code. Thread* self = Thread::Current(); diff --git a/test/etc/run-test-jar b/test/etc/run-test-jar index 39dc0301d9..f45e6f5865 100755 --- a/test/etc/run-test-jar +++ b/test/etc/run-test-jar @@ -37,9 +37,9 @@ PREBUILD="y" QUIET="n" RELOCATE="y" SECONDARY_DEX="" -TIME_OUT="y" -# Value in minutes. -TIME_OUT_VALUE=10 +TIME_OUT="gdb" # "n" (disabled), "timeout" (use timeout), "gdb" (use gdb) +# Value in seconds +TIME_OUT_VALUE=600 # 10 minutes. USE_GDB="n" USE_JVM="n" VERIFY="y" # y=yes,n=no,s=softfail @@ -459,15 +459,29 @@ else cmdline="$dalvikvm_cmdline" - if [ "$TIME_OUT" = "y" ]; then + if [ "$TIME_OUT" = "gdb" ]; then + if [ `uname` = "Darwin" ]; then + # Fall back to timeout on Mac. + TIME_OUT="timeout" + else + # Check if gdb is available. + gdb --eval-command="quit" > /dev/null 2>&1 + if [ $? != 0 ]; then + # gdb isn't available. Fall back to timeout. + TIME_OUT="timeout" + fi + fi + fi + + if [ "$TIME_OUT" = "timeout" ]; then # Add timeout command if time out is desired. # # Note: We use nested timeouts. The inner timeout sends SIGRTMIN+2 (usually 36) to ART, which # will induce a full thread dump before abort. However, dumping threads might deadlock, # so the outer timeout sends the regular SIGTERM after an additional minute to ensure # termination (without dumping all threads). - TIME_PLUS_ONE=$(($TIME_OUT_VALUE + 1)) - cmdline="timeout ${TIME_PLUS_ONE}m timeout -s SIGRTMIN+2 ${TIME_OUT_VALUE}m $cmdline" + TIME_PLUS_ONE=$(($TIME_OUT_VALUE + 60)) + cmdline="timeout ${TIME_PLUS_ONE}s timeout -s SIGRTMIN+2 ${TIME_OUT_VALUE}s $cmdline" fi if [ "$DEV_MODE" = "y" ]; then @@ -502,12 +516,37 @@ else # When running under gdb, we cannot do piping and grepping... $cmdline "$@" else - trap 'kill -INT -$pid' INT - $cmdline "$@" 2>&1 & pid=$! - wait $pid - # Add extra detail if time out is enabled. - if [ ${PIPESTATUS[0]} = 124 ] && [ "$TIME_OUT" = "y" ]; then - echo -e "\e[91mTEST TIMED OUT!\e[0m" >&2 + if [ "$TIME_OUT" != "gdb" ]; then + trap 'kill -INT -$pid' INT + $cmdline "$@" 2>&1 & pid=$! + wait $pid + # Add extra detail if time out is enabled. + if [ ${PIPESTATUS[0]} = 124 ] && [ "$TIME_OUT" = "timeout" ]; then + echo -e "\e[91mTEST TIMED OUT!\e[0m" >&2 + fi + else + # With a thread dump that uses gdb if a timeout. + trap 'kill -INT -$pid' INT + $cmdline "$@" 2>&1 & pid=$! + # Spawn a watcher process. + ( sleep $TIME_OUT_VALUE && \ + echo "##### Thread dump using gdb on test timeout" && \ + ( gdb -q -p $pid --eval-command="info thread" --eval-command="thread apply all bt" \ + --eval-command="call exit(124)" --eval-command=quit || \ + kill $pid )) 2> /dev/null & watcher=$! + wait $pid + test_exit_status=$? + pkill -P $watcher 2> /dev/null # kill the sleep which will in turn end the watcher as well + if [ $test_exit_status = 0 ]; then + # The test finished normally. + exit 0 + else + # The test failed or timed out. + if [ $test_exit_status = 124 ]; then + # The test timed out. + echo -e "\e[91mTEST TIMED OUT!\e[0m" >&2 + fi + fi fi fi fi |