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. 5603bf174e41488879ad5a7a74896669b7431ad31aDavid Srbecky printf("Going to sleep\n"); 577381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe for (;;) { 587381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe pause(); 597381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe } 607381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe} 617381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe 627381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe// Helper to look for a sequence in the stack trace. 637381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe#if __linux__ 647381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampestatic bool CheckStack(Backtrace* bt, const std::vector<std::string>& seq) { 657381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe size_t cur_search_index = 0; // The currently active index in seq. 667381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe CHECK_GT(seq.size(), 0U); 677381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe 687381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe for (Backtrace::const_iterator it = bt->begin(); it != bt->end(); ++it) { 697381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe if (BacktraceMap::IsValid(it->map)) { 707381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe LOG(INFO) << "Got " << it->func_name << ", looking for " << seq[cur_search_index]; 717381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe if (it->func_name == seq[cur_search_index]) { 727381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe cur_search_index++; 737381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe if (cur_search_index == seq.size()) { 747381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe return true; 757381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe } 767381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe } 777381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe } 787381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe } 797381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe 8091d65e024846717fce3572106cffe9b957b8902cRoland Levillain printf("Cannot find %s in backtrace:\n", seq[cur_search_index].c_str()); 81020c543382a44400576ac41686a366695316feedDavid Srbecky for (Backtrace::const_iterator it = bt->begin(); it != bt->end(); ++it) { 82020c543382a44400576ac41686a366695316feedDavid Srbecky if (BacktraceMap::IsValid(it->map)) { 83020c543382a44400576ac41686a366695316feedDavid Srbecky printf(" %s\n", it->func_name.c_str()); 84020c543382a44400576ac41686a366695316feedDavid Srbecky } 85020c543382a44400576ac41686a366695316feedDavid Srbecky } 86020c543382a44400576ac41686a366695316feedDavid Srbecky 877381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe return false; 887381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe} 897381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe#endif 907381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe 9188da3b0d2f76b1d6b9749315ac0c5b0367e92262Andreas Gampe// Currently we have to fall back to our own loader for the boot image when it's compiled PIC 9288da3b0d2f76b1d6b9749315ac0c5b0367e92262Andreas Gampe// because its base is zero. Thus in-process unwinding through it won't work. This is a helper 9388da3b0d2f76b1d6b9749315ac0c5b0367e92262Andreas Gampe// detecting this. 9488da3b0d2f76b1d6b9749315ac0c5b0367e92262Andreas Gampe#if __linux__ 9588da3b0d2f76b1d6b9749315ac0c5b0367e92262Andreas Gampestatic bool IsPicImage() { 96dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao std::vector<gc::space::ImageSpace*> image_spaces = 97dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao Runtime::Current()->GetHeap()->GetBootImageSpaces(); 98dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao CHECK(!image_spaces.empty()); // We should be running with an image. 99dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao const OatFile* oat_file = image_spaces[0]->GetOatFile(); 10088da3b0d2f76b1d6b9749315ac0c5b0367e92262Andreas Gampe CHECK(oat_file != nullptr); // We should have an oat file to go with the image. 10188da3b0d2f76b1d6b9749315ac0c5b0367e92262Andreas Gampe return oat_file->IsPic(); 10288da3b0d2f76b1d6b9749315ac0c5b0367e92262Andreas Gampe} 10388da3b0d2f76b1d6b9749315ac0c5b0367e92262Andreas Gampe#endif 10488da3b0d2f76b1d6b9749315ac0c5b0367e92262Andreas Gampe 1055288611ac0f6f009aaac58c00988d684eee78f66David Srbeckyextern "C" JNIEXPORT jboolean JNICALL Java_Main_unwindInProcess( 1065288611ac0f6f009aaac58c00988d684eee78f66David Srbecky JNIEnv*, 1075288611ac0f6f009aaac58c00988d684eee78f66David Srbecky jobject, 1085288611ac0f6f009aaac58c00988d684eee78f66David Srbecky jboolean full_signatrues, 1095288611ac0f6f009aaac58c00988d684eee78f66David Srbecky jint, 1105288611ac0f6f009aaac58c00988d684eee78f66David Srbecky jboolean) { 1117381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe#if __linux__ 11288da3b0d2f76b1d6b9749315ac0c5b0367e92262Andreas Gampe if (IsPicImage()) { 11388da3b0d2f76b1d6b9749315ac0c5b0367e92262Andreas Gampe LOG(INFO) << "Image is pic, in-process unwinding check bypassed."; 11488da3b0d2f76b1d6b9749315ac0c5b0367e92262Andreas Gampe return JNI_TRUE; 11588da3b0d2f76b1d6b9749315ac0c5b0367e92262Andreas Gampe } 11688da3b0d2f76b1d6b9749315ac0c5b0367e92262Andreas Gampe 1177381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe // TODO: What to do on Valgrind? 1187381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe 1197381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe std::unique_ptr<Backtrace> bt(Backtrace::Create(BACKTRACE_CURRENT_PROCESS, GetTid())); 1207381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe if (!bt->Unwind(0, nullptr)) { 12191d65e024846717fce3572106cffe9b957b8902cRoland Levillain printf("Cannot unwind in process.\n"); 1227381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe return JNI_FALSE; 1237381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe } else if (bt->NumFrames() == 0) { 124020c543382a44400576ac41686a366695316feedDavid Srbecky printf("No frames for unwind in process.\n"); 1257381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe return JNI_FALSE; 1267381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe } 1277381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe 1287381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe // We cannot really parse an exact stack, as the optimizing compiler may inline some functions. 1297381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe // This is also risky, as deduping might play a trick on us, so the test needs to make sure that 1307381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe // only unique functions are being expected. 1315288611ac0f6f009aaac58c00988d684eee78f66David Srbecky // "mini-debug-info" does not include parameters to save space. 1327381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe std::vector<std::string> seq = { 1337381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe "Java_Main_unwindInProcess", // This function. 1345288611ac0f6f009aaac58c00988d684eee78f66David Srbecky "Main.unwindInProcess", // The corresponding Java native method frame. 1355288611ac0f6f009aaac58c00988d684eee78f66David Srbecky "int java.util.Arrays.binarySearch(java.lang.Object[], int, int, java.lang.Object, java.util.Comparator)", // Framework method. 1365288611ac0f6f009aaac58c00988d684eee78f66David Srbecky "Main.main" // The Java entry method. 1375288611ac0f6f009aaac58c00988d684eee78f66David Srbecky }; 1385288611ac0f6f009aaac58c00988d684eee78f66David Srbecky std::vector<std::string> full_seq = { 1395288611ac0f6f009aaac58c00988d684eee78f66David Srbecky "Java_Main_unwindInProcess", // This function. 1405288611ac0f6f009aaac58c00988d684eee78f66David Srbecky "boolean Main.unwindInProcess(boolean, int, boolean)", // The corresponding Java native method frame. 1413da7608aa4fddb0af7a9ee3cd8e784e5ef87e57cDavid Srbecky "int java.util.Arrays.binarySearch(java.lang.Object[], int, int, java.lang.Object, java.util.Comparator)", // Framework method. 1427381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe "void Main.main(java.lang.String[])" // The Java entry method. 1437381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe }; 1447381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe 1455288611ac0f6f009aaac58c00988d684eee78f66David Srbecky bool result = CheckStack(bt.get(), full_signatrues ? full_seq : seq); 1467381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe if (!kCauseSegfault) { 1477381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe return result ? JNI_TRUE : JNI_FALSE; 1487381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe } else { 1497381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe LOG(INFO) << "Result of check-stack: " << result; 1507381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe } 1517381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe#endif 1527381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe 1537381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe if (kCauseSegfault) { 1547381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe CauseSegfault(); 1557381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe } 1567381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe 1577381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe return JNI_FALSE; 1587381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe} 1597381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe 1607381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe#if __linux__ 1617381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampestatic constexpr int kSleepTimeMicroseconds = 50000; // 0.05 seconds 1627381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampestatic constexpr int kMaxTotalSleepTimeMicroseconds = 1000000; // 1 second 1637381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe 1647381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe// Wait for a sigstop. This code is copied from libbacktrace. 1657381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampeint wait_for_sigstop(pid_t tid, int* total_sleep_time_usec, bool* detach_failed ATTRIBUTE_UNUSED) { 1667381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe for (;;) { 1677381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe int status; 1687381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe pid_t n = TEMP_FAILURE_RETRY(waitpid(tid, &status, __WALL | WNOHANG)); 1697381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe if (n == -1) { 1707381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe PLOG(WARNING) << "waitpid failed: tid " << tid; 1717381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe break; 1727381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe } else if (n == tid) { 1737381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe if (WIFSTOPPED(status)) { 1747381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe return WSTOPSIG(status); 1757381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe } else { 1767381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe PLOG(ERROR) << "unexpected waitpid response: n=" << n << ", status=" << std::hex << status; 1777381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe break; 1787381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe } 1797381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe } 1807381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe 1817381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe if (*total_sleep_time_usec > kMaxTotalSleepTimeMicroseconds) { 1827381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe PLOG(WARNING) << "timed out waiting for stop signal: tid=" << tid; 1837381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe break; 1847381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe } 1857381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe 1867381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe usleep(kSleepTimeMicroseconds); 1877381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe *total_sleep_time_usec += kSleepTimeMicroseconds; 1887381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe } 1897381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe 1907381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe return -1; 1917381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe} 1927381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe#endif 1937381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe 1945288611ac0f6f009aaac58c00988d684eee78f66David Srbeckyextern "C" JNIEXPORT jboolean JNICALL Java_Main_unwindOtherProcess( 1955288611ac0f6f009aaac58c00988d684eee78f66David Srbecky JNIEnv*, 1965288611ac0f6f009aaac58c00988d684eee78f66David Srbecky jobject, 1975288611ac0f6f009aaac58c00988d684eee78f66David Srbecky jboolean full_signatrues, 1985288611ac0f6f009aaac58c00988d684eee78f66David Srbecky jint pid_int) { 1997381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe#if __linux__ 2007381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe // TODO: What to do on Valgrind? 2017381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe pid_t pid = static_cast<pid_t>(pid_int); 2027381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe 2037381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe // OK, this is painful. debuggerd uses ptrace to unwind other processes. 2047381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe 2057381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe if (ptrace(PTRACE_ATTACH, pid, 0, 0)) { 2067381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe // Were not able to attach, bad. 207020c543382a44400576ac41686a366695316feedDavid Srbecky printf("Failed to attach to other process.\n"); 2087381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe PLOG(ERROR) << "Failed to attach."; 209a70e5b92a629ca4028d10c9320f9d25f2832a1abDavid Srbecky kill(pid, SIGKILL); 2107381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe return JNI_FALSE; 2117381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe } 2127381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe 2137381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe kill(pid, SIGSTOP); 2147381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe 2157381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe bool detach_failed = false; 2167381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe int total_sleep_time_usec = 0; 2177381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe int signal = wait_for_sigstop(pid, &total_sleep_time_usec, &detach_failed); 2187381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe if (signal == -1) { 2197381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe LOG(WARNING) << "wait_for_sigstop failed."; 2207381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe } 2217381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe 2227381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe std::unique_ptr<Backtrace> bt(Backtrace::Create(pid, BACKTRACE_CURRENT_THREAD)); 2237381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe bool result = true; 2247381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe if (!bt->Unwind(0, nullptr)) { 22591d65e024846717fce3572106cffe9b957b8902cRoland Levillain printf("Cannot unwind other process.\n"); 2267381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe result = false; 2277381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe } else if (bt->NumFrames() == 0) { 228020c543382a44400576ac41686a366695316feedDavid Srbecky printf("No frames for unwind of other process.\n"); 2297381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe result = false; 2307381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe } 2317381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe 2327381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe if (result) { 2337381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe // See comment in unwindInProcess for non-exact stack matching. 2345288611ac0f6f009aaac58c00988d684eee78f66David Srbecky // "mini-debug-info" does not include parameters to save space. 2357381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe std::vector<std::string> seq = { 2367381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe // "Java_Main_sleep", // The sleep function being executed in the 2377381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe // other runtime. 2387381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe // Note: For some reason, the name isn't 2397381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe // resolved, so don't look for it right now. 2405288611ac0f6f009aaac58c00988d684eee78f66David Srbecky "Main.sleep", // The corresponding Java native method frame. 2415288611ac0f6f009aaac58c00988d684eee78f66David Srbecky "int java.util.Arrays.binarySearch(java.lang.Object[], int, int, java.lang.Object, java.util.Comparator)", // Framework method. 2425288611ac0f6f009aaac58c00988d684eee78f66David Srbecky "Main.main" // The Java entry method. 2435288611ac0f6f009aaac58c00988d684eee78f66David Srbecky }; 2445288611ac0f6f009aaac58c00988d684eee78f66David Srbecky std::vector<std::string> full_seq = { 2455288611ac0f6f009aaac58c00988d684eee78f66David Srbecky // "Java_Main_sleep", // The sleep function being executed in the 2465288611ac0f6f009aaac58c00988d684eee78f66David Srbecky // other runtime. 2475288611ac0f6f009aaac58c00988d684eee78f66David Srbecky // Note: For some reason, the name isn't 2485288611ac0f6f009aaac58c00988d684eee78f66David Srbecky // resolved, so don't look for it right now. 2497381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe "boolean Main.sleep(int, boolean, double)", // The corresponding Java native method frame. 2503da7608aa4fddb0af7a9ee3cd8e784e5ef87e57cDavid Srbecky "int java.util.Arrays.binarySearch(java.lang.Object[], int, int, java.lang.Object, java.util.Comparator)", // Framework method. 2517381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe "void Main.main(java.lang.String[])" // The Java entry method. 2527381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe }; 2537381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe 2545288611ac0f6f009aaac58c00988d684eee78f66David Srbecky result = CheckStack(bt.get(), full_signatrues ? full_seq : seq); 2557381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe } 2567381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe 2577381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe if (ptrace(PTRACE_DETACH, pid, 0, 0) != 0) { 2587381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe PLOG(ERROR) << "Detach failed"; 2597381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe } 2607381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe 261a70e5b92a629ca4028d10c9320f9d25f2832a1abDavid Srbecky // Kill the other process once we are done with it. 262a70e5b92a629ca4028d10c9320f9d25f2832a1abDavid Srbecky kill(pid, SIGKILL); 2637381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe 2647381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe return result ? JNI_TRUE : JNI_FALSE; 2657381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe#else 2663faa5813677472e8230b3250272491f883a4618fAndreas Gampe UNUSED(pid_int); 2677381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe return JNI_FALSE; 2687381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe#endif 2697381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe} 2707381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe 2717381010d4ea299f1aaf7c86e93341d12f5e9d2c4Andreas Gampe} // namespace art 272