1 /*
2  * Copyright (C) 2015 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #if __linux__
18 #include <errno.h>
19 #include <signal.h>
20 #include <string.h>
21 #include <sys/ptrace.h>
22 #include <sys/wait.h>
23 #include <unistd.h>
24 #endif
25 
26 #include "jni.h"
27 
28 #include <android-base/file.h>
29 #include <android-base/logging.h>
30 #include <android-base/stringprintf.h>
31 #include <unwindstack/AndroidUnwinder.h>
32 
33 #include "base/file_utils.h"
34 #include "base/logging.h"
35 #include "base/macros.h"
36 #include "base/mutex.h"
37 #include "base/utils.h"
38 #include "gc/heap.h"
39 #include "gc/space/image_space.h"
40 #include "jit/debugger_interface.h"
41 #include "oat/oat_file.h"
42 #include "runtime.h"
43 
44 namespace art {
45 
46 // For testing debuggerd. We do not have expected-death tests, so can't test this by default.
47 // Code for this is copied from SignalTest.
48 static constexpr bool kCauseSegfault = false;
49 char* go_away_compiler_cfi = nullptr;
50 
CauseSegfault()51 static void CauseSegfault() {
52 #if defined(__arm__) || defined(__i386__) || defined(__x86_64__) || defined(__aarch64__)
53   // On supported architectures we cause a real SEGV.
54   *go_away_compiler_cfi = 'a';
55 #else
56   // On other architectures we simulate SEGV.
57   kill(getpid(), SIGSEGV);
58 #endif
59 }
60 
Java_Main_startSecondaryProcess(JNIEnv *,jclass)61 extern "C" JNIEXPORT jint JNICALL Java_Main_startSecondaryProcess(JNIEnv*, jclass) {
62   printf("Java_Main_startSecondaryProcess\n");
63 #if __linux__
64   // Get our command line so that we can use it to start identical process.
65   std::string cmdline;  // null-separated and null-terminated arguments.
66   if (!android::base::ReadFileToString("/proc/self/cmdline", &cmdline)) {
67     LOG(FATAL) << "Failed to read /proc/self/cmdline.";
68   }
69   if (cmdline.empty()) {
70     LOG(FATAL) << "No data was read from /proc/self/cmdline.";
71   }
72   // Workaround for b/150189787.
73   if (cmdline.back() != '\0') {
74     cmdline += '\0';
75   }
76   cmdline = cmdline + "--secondary" + '\0';  // Let the child know it is a helper.
77 
78   // Split the string into individual arguments suitable for execv.
79   std::vector<char*> argv;
80   for (size_t i = 0; i < cmdline.size(); i += strlen(&cmdline[i]) + 1) {
81     argv.push_back(&cmdline[i]);
82   }
83   argv.push_back(nullptr);  // Terminate the list.
84 
85   pid_t pid = fork();
86   if (pid < 0) {
87     LOG(FATAL) << "Fork failed";
88   } else if (pid == 0) {
89     execv(argv[0], argv.data());
90     exit(1);
91   }
92   return pid;
93 #else
94   return 0;
95 #endif
96 }
97 
Java_Main_sigstop(JNIEnv *,jclass)98 extern "C" JNIEXPORT jboolean JNICALL Java_Main_sigstop(JNIEnv*, jclass) {
99   printf("Java_Main_sigstop\n");
100 #if __linux__
101   MutexLock mu(Thread::Current(), *GetNativeDebugInfoLock());  // Avoid races with the JIT thread.
102   raise(SIGSTOP);
103 #endif
104   return true;  // Prevent the compiler from tail-call optimizing this method away.
105 }
106 
107 // Helper to look for a sequence in the stack trace.
108 #if __linux__
CheckStack(unwindstack::AndroidUnwinder & unwinder,unwindstack::AndroidUnwinderData & data,const std::vector<std::string> & seq)109 static bool CheckStack(unwindstack::AndroidUnwinder& unwinder,
110                        unwindstack::AndroidUnwinderData& data,
111                        const std::vector<std::string>& seq) {
112   size_t cur_search_index = 0;  // The currently active index in seq.
113   CHECK_GT(seq.size(), 0U);
114 
115   bool ok = true;
116   for (const unwindstack::FrameData& frame : data.frames) {
117     if (frame.map_info == nullptr) {
118       printf("Error: No map_info for frame #%02zu\n", frame.num);
119       ok = false;
120       continue;
121     }
122     const std::string& function_name = frame.function_name;
123     if (cur_search_index < seq.size()) {
124       LOG(INFO) << "Got " << function_name << ", looking for " << seq[cur_search_index];
125       if (function_name.find(seq[cur_search_index]) != std::string::npos) {
126         cur_search_index++;
127       }
128     }
129     if (function_name == "main") {
130       break;
131     }
132 #if !defined(__ANDROID__) && defined(__BIONIC__ )  // host-bionic
133     // TODO(b/182810709): Unwinding is broken on host-bionic so we expect some empty frames.
134 #else
135     const std::string& lib_name = frame.map_info->name();
136     if (!kIsTargetBuild && lib_name.find("libc.so") != std::string::npos) {
137       // TODO(b/254626913): Unwinding can fail for libc on host.
138     } else if (function_name.empty()) {
139       printf("Error: No function name for frame #%02zu\n", frame.num);
140       ok = false;
141     }
142 #endif
143   }
144 
145   if (cur_search_index < seq.size()) {
146     printf("Error: Cannot find %s\n", seq[cur_search_index].c_str());
147     ok = false;
148   }
149 
150   if (!ok) {
151     printf("Backtrace:\n");
152     for (const unwindstack::FrameData& frame : data.frames) {
153       printf("  %s\n", unwinder.FormatFrame(frame).c_str());
154     }
155   }
156 
157   return ok;
158 }
159 
MoreErrorInfo(pid_t pid,bool sig_quit_on_fail)160 static void MoreErrorInfo(pid_t pid, bool sig_quit_on_fail) {
161   PrintFileToLog(android::base::StringPrintf("/proc/%d/maps", pid), ::android::base::ERROR);
162 
163   if (sig_quit_on_fail) {
164     int res = kill(pid, SIGQUIT);
165     if (res != 0) {
166       PLOG(ERROR) << "Failed to send signal";
167     }
168   }
169 }
170 #endif
171 
Java_Main_unwindInProcess(JNIEnv *,jclass)172 extern "C" JNIEXPORT jboolean JNICALL Java_Main_unwindInProcess(JNIEnv*, jclass) {
173   printf("Java_Main_unwindInProcess\n");
174 #if __linux__
175   MutexLock mu(Thread::Current(), *GetNativeDebugInfoLock());  // Avoid races with the JIT thread.
176 
177   unwindstack::AndroidLocalUnwinder unwinder;
178   unwindstack::AndroidUnwinderData data;
179   if (!unwinder.Unwind(data)) {
180     printf("Cannot unwind in process.\n");
181     return JNI_FALSE;
182   }
183 
184   // We cannot really parse an exact stack, as the optimizing compiler may inline some functions.
185   // This is also risky, as deduping might play a trick on us, so the test needs to make sure that
186   // only unique functions are being expected.
187   // "mini-debug-info" does not include parameters to save space.
188   std::vector<std::string> seq = {
189       "Java_Main_unwindInProcess",       // This function.
190       "java.util.Arrays.binarySearch0",  // Framework method.
191       "Base.$noinline$runTest",          // Method in other dex file.
192       "Main.main"                        // The Java entry method.
193   };
194 
195   bool result = CheckStack(unwinder, data, seq);
196   if (!kCauseSegfault) {
197     return result ? JNI_TRUE : JNI_FALSE;
198   } else {
199     LOG(INFO) << "Result of check-stack: " << result;
200   }
201 #endif
202 
203   if (kCauseSegfault) {
204     CauseSegfault();
205   }
206 
207   return JNI_FALSE;
208 }
209 
210 #if __linux__
211 static constexpr int kSleepTimeMicroseconds = 50000;             // 0.05 seconds
212 static constexpr int kMaxTotalSleepTimeMicroseconds = 10000000;  // 10 seconds
213 
214 // Wait for a sigstop. This code is copied from libbacktrace.
wait_for_sigstop(pid_t tid,int * total_sleep_time_usec,bool * detach_failed)215 int wait_for_sigstop(pid_t tid, int* total_sleep_time_usec, [[maybe_unused]] bool* detach_failed) {
216   for (;;) {
217     int status;
218     pid_t n = TEMP_FAILURE_RETRY(waitpid(tid, &status, __WALL | WNOHANG | WUNTRACED));
219     if (n == -1) {
220       PLOG(WARNING) << "waitpid failed: tid " << tid;
221       break;
222     } else if (n == tid) {
223       if (WIFSTOPPED(status)) {
224         return WSTOPSIG(status);
225       } else {
226         PLOG(ERROR) << "unexpected waitpid response: n=" << n << ", status=" << std::hex << status;
227         break;
228       }
229     }
230 
231     if (*total_sleep_time_usec > kMaxTotalSleepTimeMicroseconds) {
232       PLOG(WARNING) << "timed out waiting for stop signal: tid=" << tid;
233       break;
234     }
235 
236     usleep(kSleepTimeMicroseconds);
237     *total_sleep_time_usec += kSleepTimeMicroseconds;
238   }
239 
240   return -1;
241 }
242 #endif
243 
Java_Main_unwindOtherProcess(JNIEnv *,jclass,jint pid_int)244 extern "C" JNIEXPORT jboolean JNICALL Java_Main_unwindOtherProcess(JNIEnv*, jclass, jint pid_int) {
245   printf("Java_Main_unwindOtherProcess\n");
246 #if __linux__
247   pid_t pid = static_cast<pid_t>(pid_int);
248 
249   // We wait for the SIGSTOP while the child process is untraced (using
250   // `WUNTRACED` in `wait_for_sigstop()`) to avoid a SIGSEGV for implicit
251   // suspend check stopping the process because it's being traced.
252   bool detach_failed = false;
253   int total_sleep_time_usec = 0;
254   int signal = wait_for_sigstop(pid, &total_sleep_time_usec, &detach_failed);
255   if (signal != SIGSTOP) {
256     printf("wait_for_sigstop failed.\n");
257     return JNI_FALSE;
258   }
259 
260   // SEIZE is like ATTACH, but it does not stop the process (it has already stopped itself).
261   if (ptrace(PTRACE_SEIZE, pid, 0, 0)) {
262     // Were not able to attach, bad.
263     printf("Failed to attach to other process.\n");
264     PLOG(ERROR) << "Failed to attach.";
265     kill(pid, SIGKILL);
266     return JNI_FALSE;
267   }
268 
269   bool result = true;
270   unwindstack::AndroidRemoteUnwinder unwinder(pid);
271   unwindstack::AndroidUnwinderData data;
272   if (!unwinder.Unwind(data)) {
273     printf("Cannot unwind other process.\n");
274     result = false;
275   } else {
276     // See comment in unwindInProcess for non-exact stack matching.
277     // "mini-debug-info" does not include parameters to save space.
278     std::vector<std::string> seq = {
279         "Java_Main_sigstop",                // The stop function in the other process.
280         "java.util.Arrays.binarySearch0",   // Framework method.
281         "Base.$noinline$runTest",           // Method in other dex file.
282         "Main.main"                         // The Java entry method.
283     };
284 
285     result = CheckStack(unwinder, data, seq);
286   }
287 
288   constexpr bool kSigQuitOnFail = true;
289   if (!result) {
290     printf("Failed to unwind secondary with pid %d\n", pid);
291     MoreErrorInfo(pid, kSigQuitOnFail);
292   }
293 
294   if (ptrace(PTRACE_DETACH, pid, 0, 0) != 0) {
295     printf("Detach failed\n");
296     PLOG(ERROR) << "Detach failed";
297   }
298 
299   // If we failed to unwind and induced an ANR dump, give the child some time (20s).
300   if (!result && kSigQuitOnFail) {
301     sleep(20);
302   }
303 
304   // Kill the other process once we are done with it.
305   kill(pid, SIGKILL);
306 
307   return result ? JNI_TRUE : JNI_FALSE;
308 #else
309   printf("Remote unwind supported only on linux\n");
310   UNUSED(pid_int);
311   return JNI_FALSE;
312 #endif
313 }
314 
315 }  // namespace art
316