cfi.cc revision dcdc85bbd569f0ee66c331b4219c19304a616214
17381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe/* 27381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe * Copyright (C) 2015 The Android Open Source Project 37381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe * 47381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe * Licensed under the Apache License, Version 2.0 (the "License"); 57381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe * you may not use this file except in compliance with the License. 67381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe * You may obtain a copy of the License at 77381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe * 87381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe * http://www.apache.org/licenses/LICENSE-2.0 97381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe * 107381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe * Unless required by applicable law or agreed to in writing, software 117381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe * distributed under the License is distributed on an "AS IS" BASIS, 127381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 137381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe * See the License for the specific language governing permissions and 147381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe * limitations under the License. 157381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe */ 167381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe 177381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe#if __linux__ 187381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe#include <errno.h> 197381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe#include <signal.h> 207381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe#include <string.h> 217381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe#include <unistd.h> 227381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe#include <sys/ptrace.h> 237381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe#include <sys/wait.h> 247381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe#endif 257381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe 267381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe#include "jni.h" 277381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe 287381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe#include <backtrace/Backtrace.h> 297381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe 307381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe#include "base/logging.h" 317381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe#include "base/macros.h" 3288da3b0d2f76b1d6b9749315ac0c5b0367e92262Andreas Gampe#include "gc/heap.h" 3388da3b0d2f76b1d6b9749315ac0c5b0367e92262Andreas Gampe#include "gc/space/image_space.h" 3488da3b0d2f76b1d6b9749315ac0c5b0367e92262Andreas Gampe#include "oat_file.h" 357381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe#include "utils.h" 367381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe 377381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampenamespace art { 387381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe 397381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe// For testing debuggerd. We do not have expected-death tests, so can't test this by default. 407381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe// Code for this is copied from SignalTest. 417381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampestatic constexpr bool kCauseSegfault = false; 427381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampechar* go_away_compiler_cfi = nullptr; 437381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe 447381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampestatic void CauseSegfault() { 457381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe#if defined(__arm__) || defined(__i386__) || defined(__x86_64__) || defined(__aarch64__) 467381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe // On supported architectures we cause a real SEGV. 477381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe *go_away_compiler_cfi = 'a'; 487381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe#else 497381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe // On other architectures we simulate SEGV. 507381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe kill(getpid(), SIGSEGV); 517381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe#endif 527381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe} 537381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe 547381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampeextern "C" JNIEXPORT jboolean JNICALL Java_Main_sleep(JNIEnv*, jobject, jint, jboolean, jdouble) { 557381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe // Keep pausing. 567381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe for (;;) { 577381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe pause(); 587381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe } 597381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe} 607381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe 617381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe// Helper to look for a sequence in the stack trace. 627381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe#if __linux__ 637381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampestatic bool CheckStack(Backtrace* bt, const std::vector<std::string>& seq) { 647381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe size_t cur_search_index = 0; // The currently active index in seq. 657381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe CHECK_GT(seq.size(), 0U); 667381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe 677381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe for (Backtrace::const_iterator it = bt->begin(); it != bt->end(); ++it) { 687381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe if (BacktraceMap::IsValid(it->map)) { 697381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe LOG(INFO) << "Got " << it->func_name << ", looking for " << seq[cur_search_index]; 707381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe if (it->func_name == seq[cur_search_index]) { 717381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe cur_search_index++; 727381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe if (cur_search_index == seq.size()) { 737381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe return true; 747381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe } 757381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe } 767381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe } 777381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe } 787381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe 79020c543382a44400576ac41686a366695316feedDavid Srbecky printf("Can not find %s in backtrace:\n", seq[cur_search_index].c_str()); 80020c543382a44400576ac41686a366695316feedDavid Srbecky for (Backtrace::const_iterator it = bt->begin(); it != bt->end(); ++it) { 81020c543382a44400576ac41686a366695316feedDavid Srbecky if (BacktraceMap::IsValid(it->map)) { 82020c543382a44400576ac41686a366695316feedDavid Srbecky printf(" %s\n", it->func_name.c_str()); 83020c543382a44400576ac41686a366695316feedDavid Srbecky } 84020c543382a44400576ac41686a366695316feedDavid Srbecky } 85020c543382a44400576ac41686a366695316feedDavid Srbecky 867381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe return false; 877381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe} 887381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe#endif 897381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe 9088da3b0d2f76b1d6b9749315ac0c5b0367e92262Andreas Gampe// Currently we have to fall back to our own loader for the boot image when it's compiled PIC 9188da3b0d2f76b1d6b9749315ac0c5b0367e92262Andreas Gampe// because its base is zero. Thus in-process unwinding through it won't work. This is a helper 9288da3b0d2f76b1d6b9749315ac0c5b0367e92262Andreas Gampe// detecting this. 9388da3b0d2f76b1d6b9749315ac0c5b0367e92262Andreas Gampe#if __linux__ 9488da3b0d2f76b1d6b9749315ac0c5b0367e92262Andreas Gampestatic bool IsPicImage() { 95dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao std::vector<gc::space::ImageSpace*> image_spaces = 96dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao Runtime::Current()->GetHeap()->GetBootImageSpaces(); 97dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao CHECK(!image_spaces.empty()); // We should be running with an image. 98dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao const OatFile* oat_file = image_spaces[0]->GetOatFile(); 9988da3b0d2f76b1d6b9749315ac0c5b0367e92262Andreas Gampe CHECK(oat_file != nullptr); // We should have an oat file to go with the image. 10088da3b0d2f76b1d6b9749315ac0c5b0367e92262Andreas Gampe return oat_file->IsPic(); 10188da3b0d2f76b1d6b9749315ac0c5b0367e92262Andreas Gampe} 10288da3b0d2f76b1d6b9749315ac0c5b0367e92262Andreas Gampe#endif 10388da3b0d2f76b1d6b9749315ac0c5b0367e92262Andreas Gampe 1047381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampeextern "C" JNIEXPORT jboolean JNICALL Java_Main_unwindInProcess(JNIEnv*, jobject, jint, jboolean) { 1057381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe#if __linux__ 10688da3b0d2f76b1d6b9749315ac0c5b0367e92262Andreas Gampe if (IsPicImage()) { 10788da3b0d2f76b1d6b9749315ac0c5b0367e92262Andreas Gampe LOG(INFO) << "Image is pic, in-process unwinding check bypassed."; 10888da3b0d2f76b1d6b9749315ac0c5b0367e92262Andreas Gampe return JNI_TRUE; 10988da3b0d2f76b1d6b9749315ac0c5b0367e92262Andreas Gampe } 11088da3b0d2f76b1d6b9749315ac0c5b0367e92262Andreas Gampe 1117381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe // TODO: What to do on Valgrind? 1127381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe 1137381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe std::unique_ptr<Backtrace> bt(Backtrace::Create(BACKTRACE_CURRENT_PROCESS, GetTid())); 1147381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe if (!bt->Unwind(0, nullptr)) { 115020c543382a44400576ac41686a366695316feedDavid Srbecky printf("Can not unwind in process.\n"); 1167381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe return JNI_FALSE; 1177381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe } else if (bt->NumFrames() == 0) { 118020c543382a44400576ac41686a366695316feedDavid Srbecky printf("No frames for unwind in process.\n"); 1197381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe return JNI_FALSE; 1207381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe } 1217381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe 1227381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe // We cannot really parse an exact stack, as the optimizing compiler may inline some functions. 1237381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe // This is also risky, as deduping might play a trick on us, so the test needs to make sure that 1247381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe // only unique functions are being expected. 1257381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe std::vector<std::string> seq = { 1267381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe "Java_Main_unwindInProcess", // This function. 1277381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe "boolean Main.unwindInProcess(int, boolean)", // The corresponding Java native method frame. 1283da7608aa4fddb0af7a9ee3cd8e784e5ef87e57cDavid Srbecky "int java.util.Arrays.binarySearch(java.lang.Object[], int, int, java.lang.Object, java.util.Comparator)", // Framework method. 1297381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe "void Main.main(java.lang.String[])" // The Java entry method. 1307381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe }; 1317381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe 1327381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe bool result = CheckStack(bt.get(), seq); 1337381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe if (!kCauseSegfault) { 1347381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe return result ? JNI_TRUE : JNI_FALSE; 1357381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe } else { 1367381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe LOG(INFO) << "Result of check-stack: " << result; 1377381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe } 1387381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe#endif 1397381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe 1407381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe if (kCauseSegfault) { 1417381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe CauseSegfault(); 1427381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe } 1437381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe 1447381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe return JNI_FALSE; 1457381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe} 1467381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe 1477381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe#if __linux__ 1487381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampestatic constexpr int kSleepTimeMicroseconds = 50000; // 0.05 seconds 1497381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampestatic constexpr int kMaxTotalSleepTimeMicroseconds = 1000000; // 1 second 1507381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe 1517381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe// Wait for a sigstop. This code is copied from libbacktrace. 1527381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampeint wait_for_sigstop(pid_t tid, int* total_sleep_time_usec, bool* detach_failed ATTRIBUTE_UNUSED) { 1537381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe for (;;) { 1547381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe int status; 1557381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe pid_t n = TEMP_FAILURE_RETRY(waitpid(tid, &status, __WALL | WNOHANG)); 1567381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe if (n == -1) { 1577381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe PLOG(WARNING) << "waitpid failed: tid " << tid; 1587381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe break; 1597381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe } else if (n == tid) { 1607381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe if (WIFSTOPPED(status)) { 1617381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe return WSTOPSIG(status); 1627381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe } else { 1637381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe PLOG(ERROR) << "unexpected waitpid response: n=" << n << ", status=" << std::hex << status; 1647381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe break; 1657381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe } 1667381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe } 1677381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe 1687381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe if (*total_sleep_time_usec > kMaxTotalSleepTimeMicroseconds) { 1697381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe PLOG(WARNING) << "timed out waiting for stop signal: tid=" << tid; 1707381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe break; 1717381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe } 1727381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe 1737381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe usleep(kSleepTimeMicroseconds); 1747381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe *total_sleep_time_usec += kSleepTimeMicroseconds; 1757381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe } 1767381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe 1777381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe return -1; 1787381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe} 1797381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe#endif 1807381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe 1817381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampeextern "C" JNIEXPORT jboolean JNICALL Java_Main_unwindOtherProcess(JNIEnv*, jobject, jint pid_int) { 1827381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe#if __linux__ 1837381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe // TODO: What to do on Valgrind? 1847381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe pid_t pid = static_cast<pid_t>(pid_int); 1857381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe 1867381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe // OK, this is painful. debuggerd uses ptrace to unwind other processes. 1877381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe 1887381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe if (ptrace(PTRACE_ATTACH, pid, 0, 0)) { 1897381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe // Were not able to attach, bad. 190020c543382a44400576ac41686a366695316feedDavid Srbecky printf("Failed to attach to other process.\n"); 1917381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe PLOG(ERROR) << "Failed to attach."; 192a70e5b92a629ca4028d10c9320f9d25f2832a1abDavid Srbecky kill(pid, SIGKILL); 1937381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe return JNI_FALSE; 1947381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe } 1957381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe 1967381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe kill(pid, SIGSTOP); 1977381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe 1987381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe bool detach_failed = false; 1997381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe int total_sleep_time_usec = 0; 2007381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe int signal = wait_for_sigstop(pid, &total_sleep_time_usec, &detach_failed); 2017381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe if (signal == -1) { 2027381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe LOG(WARNING) << "wait_for_sigstop failed."; 2037381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe } 2047381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe 2057381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe std::unique_ptr<Backtrace> bt(Backtrace::Create(pid, BACKTRACE_CURRENT_THREAD)); 2067381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe bool result = true; 2077381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe if (!bt->Unwind(0, nullptr)) { 208020c543382a44400576ac41686a366695316feedDavid Srbecky printf("Can not unwind other process.\n"); 2097381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe result = false; 2107381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe } else if (bt->NumFrames() == 0) { 211020c543382a44400576ac41686a366695316feedDavid Srbecky printf("No frames for unwind of other process.\n"); 2127381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe result = false; 2137381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe } 2147381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe 2157381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe if (result) { 2167381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe // See comment in unwindInProcess for non-exact stack matching. 2177381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe std::vector<std::string> seq = { 2187381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe // "Java_Main_sleep", // The sleep function being executed in the 2197381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe // other runtime. 2207381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe // Note: For some reason, the name isn't 2217381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe // resolved, so don't look for it right now. 2227381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe "boolean Main.sleep(int, boolean, double)", // The corresponding Java native method frame. 2233da7608aa4fddb0af7a9ee3cd8e784e5ef87e57cDavid Srbecky "int java.util.Arrays.binarySearch(java.lang.Object[], int, int, java.lang.Object, java.util.Comparator)", // Framework method. 2247381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe "void Main.main(java.lang.String[])" // The Java entry method. 2257381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe }; 2267381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe 2277381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe result = CheckStack(bt.get(), seq); 2287381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe } 2297381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe 2307381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe if (ptrace(PTRACE_DETACH, pid, 0, 0) != 0) { 2317381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe PLOG(ERROR) << "Detach failed"; 2327381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe } 2337381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe 234a70e5b92a629ca4028d10c9320f9d25f2832a1abDavid Srbecky // Kill the other process once we are done with it. 235a70e5b92a629ca4028d10c9320f9d25f2832a1abDavid Srbecky kill(pid, SIGKILL); 2367381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe 2377381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe return result ? JNI_TRUE : JNI_FALSE; 2387381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe#else 2393faa5813677472e8230b3250272491f883a4618fAndreas Gampe UNUSED(pid_int); 2407381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe return JNI_FALSE; 2417381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe#endif 2427381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe} 2437381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe 2447381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe} // namespace art 245