1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* system/debuggerd/utility.c 2dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** 3dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** Copyright 2008, The Android Open Source Project 4dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** 5dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License"); 6dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** you may not use this file except in compliance with the License. 7dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** You may obtain a copy of the License at 8dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** 9dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** http://www.apache.org/licenses/LICENSE-2.0 10dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** 11dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** Unless required by applicable law or agreed to in writing, software 12dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** distributed under the License is distributed on an "AS IS" BASIS, 13dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** See the License for the specific language governing permissions and 15dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** limitations under the License. 16dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project*/ 17dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 18053b865412d1982ad1dc0e840898d82527deeb99Jeff Brown#include <stddef.h> 19053b865412d1982ad1dc0e840898d82527deeb99Jeff Brown#include <stdbool.h> 20053b865412d1982ad1dc0e840898d82527deeb99Jeff Brown#include <stdio.h> 21dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <string.h> 22053b865412d1982ad1dc0e840898d82527deeb99Jeff Brown#include <errno.h> 23053b865412d1982ad1dc0e840898d82527deeb99Jeff Brown#include <unistd.h> 24053b865412d1982ad1dc0e840898d82527deeb99Jeff Brown#include <signal.h> 259227bd385504ace739d4451a6c5dc3d777b5bf21Colin Cross#include <log/logd.h> 2613e715b491e876865e752a3a69dd6f347049a488Jeff Brown#include <sys/ptrace.h> 27053b865412d1982ad1dc0e840898d82527deeb99Jeff Brown#include <sys/wait.h> 28ded2e5acfcf0c705f08577d0ccb720bd5037f4baChristopher Tate#include <arpa/inet.h> 29ded2e5acfcf0c705f08577d0ccb720bd5037f4baChristopher Tate#include <assert.h> 30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 31dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "utility.h" 32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 33053b865412d1982ad1dc0e840898d82527deeb99Jeff Brownconst int sleep_time_usec = 50000; /* 0.05 seconds */ 34053b865412d1982ad1dc0e840898d82527deeb99Jeff Brownconst int max_total_sleep_usec = 10000000; /* 10 seconds */ 3513e715b491e876865e752a3a69dd6f347049a488Jeff Brown 36ded2e5acfcf0c705f08577d0ccb720bd5037f4baChristopher Tatestatic int write_to_am(int fd, const char* buf, int len) { 37ded2e5acfcf0c705f08577d0ccb720bd5037f4baChristopher Tate int to_write = len; 38ded2e5acfcf0c705f08577d0ccb720bd5037f4baChristopher Tate while (to_write > 0) { 39ded2e5acfcf0c705f08577d0ccb720bd5037f4baChristopher Tate int written = TEMP_FAILURE_RETRY( write(fd, buf + len - to_write, to_write) ); 40ded2e5acfcf0c705f08577d0ccb720bd5037f4baChristopher Tate if (written < 0) { 41ded2e5acfcf0c705f08577d0ccb720bd5037f4baChristopher Tate /* hard failure */ 427716aef138e8029357a7b3dc6a73b41f4de4b0adChristopher Tate LOG("AM write failure (%d / %s)\n", errno, strerror(errno)); 43ded2e5acfcf0c705f08577d0ccb720bd5037f4baChristopher Tate return -1; 44ded2e5acfcf0c705f08577d0ccb720bd5037f4baChristopher Tate } 45ded2e5acfcf0c705f08577d0ccb720bd5037f4baChristopher Tate to_write -= written; 46ded2e5acfcf0c705f08577d0ccb720bd5037f4baChristopher Tate } 47ded2e5acfcf0c705f08577d0ccb720bd5037f4baChristopher Tate return len; 48ded2e5acfcf0c705f08577d0ccb720bd5037f4baChristopher Tate} 49ded2e5acfcf0c705f08577d0ccb720bd5037f4baChristopher Tate 507716aef138e8029357a7b3dc6a73b41f4de4b0adChristopher Tatevoid _LOG(log_t* log, int scopeFlags, const char *fmt, ...) { 5113e715b491e876865e752a3a69dd6f347049a488Jeff Brown char buf[512]; 52ded2e5acfcf0c705f08577d0ccb720bd5037f4baChristopher Tate bool want_tfd_write; 53ded2e5acfcf0c705f08577d0ccb720bd5037f4baChristopher Tate bool want_log_write; 54ded2e5acfcf0c705f08577d0ccb720bd5037f4baChristopher Tate bool want_amfd_write; 557716aef138e8029357a7b3dc6a73b41f4de4b0adChristopher Tate int len = 0; 5613e715b491e876865e752a3a69dd6f347049a488Jeff Brown 5713e715b491e876865e752a3a69dd6f347049a488Jeff Brown va_list ap; 5813e715b491e876865e752a3a69dd6f347049a488Jeff Brown va_start(ap, fmt); 5913e715b491e876865e752a3a69dd6f347049a488Jeff Brown 60ded2e5acfcf0c705f08577d0ccb720bd5037f4baChristopher Tate // where is the information going to go? 617716aef138e8029357a7b3dc6a73b41f4de4b0adChristopher Tate want_tfd_write = log && log->tfd >= 0; 627716aef138e8029357a7b3dc6a73b41f4de4b0adChristopher Tate want_log_write = IS_AT_FAULT(scopeFlags) && (!log || !log->quiet); 637716aef138e8029357a7b3dc6a73b41f4de4b0adChristopher Tate want_amfd_write = IS_AT_FAULT(scopeFlags) && !IS_SENSITIVE(scopeFlags) && log && log->amfd >= 0; 64ded2e5acfcf0c705f08577d0ccb720bd5037f4baChristopher Tate 65ded2e5acfcf0c705f08577d0ccb720bd5037f4baChristopher Tate // if we're going to need the literal string, generate it once here 66ded2e5acfcf0c705f08577d0ccb720bd5037f4baChristopher Tate if (want_tfd_write || want_amfd_write) { 6713e715b491e876865e752a3a69dd6f347049a488Jeff Brown vsnprintf(buf, sizeof(buf), fmt, ap); 6813e715b491e876865e752a3a69dd6f347049a488Jeff Brown len = strlen(buf); 69ded2e5acfcf0c705f08577d0ccb720bd5037f4baChristopher Tate } 70ded2e5acfcf0c705f08577d0ccb720bd5037f4baChristopher Tate 71ded2e5acfcf0c705f08577d0ccb720bd5037f4baChristopher Tate if (want_tfd_write) { 72053b865412d1982ad1dc0e840898d82527deeb99Jeff Brown write(log->tfd, buf, len); 7313e715b491e876865e752a3a69dd6f347049a488Jeff Brown } 7413e715b491e876865e752a3a69dd6f347049a488Jeff Brown 75ded2e5acfcf0c705f08577d0ccb720bd5037f4baChristopher Tate if (want_log_write) { 76ded2e5acfcf0c705f08577d0ccb720bd5037f4baChristopher Tate // whatever goes to logcat also goes to the Activity Manager 7713e715b491e876865e752a3a69dd6f347049a488Jeff Brown __android_log_vprint(ANDROID_LOG_INFO, "DEBUG", fmt, ap); 78ded2e5acfcf0c705f08577d0ccb720bd5037f4baChristopher Tate if (want_amfd_write && len > 0) { 79ded2e5acfcf0c705f08577d0ccb720bd5037f4baChristopher Tate int written = write_to_am(log->amfd, buf, len); 80ded2e5acfcf0c705f08577d0ccb720bd5037f4baChristopher Tate if (written <= 0) { 81ded2e5acfcf0c705f08577d0ccb720bd5037f4baChristopher Tate // timeout or other failure on write; stop informing the activity manager 82ded2e5acfcf0c705f08577d0ccb720bd5037f4baChristopher Tate log->amfd = -1; 83ded2e5acfcf0c705f08577d0ccb720bd5037f4baChristopher Tate } 84ded2e5acfcf0c705f08577d0ccb720bd5037f4baChristopher Tate } 8513e715b491e876865e752a3a69dd6f347049a488Jeff Brown } 86053b865412d1982ad1dc0e840898d82527deeb99Jeff Brown va_end(ap); 8713e715b491e876865e752a3a69dd6f347049a488Jeff Brown} 88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 89053b865412d1982ad1dc0e840898d82527deeb99Jeff Brownint wait_for_signal(pid_t tid, int* total_sleep_time_usec) { 90053b865412d1982ad1dc0e840898d82527deeb99Jeff Brown for (;;) { 91053b865412d1982ad1dc0e840898d82527deeb99Jeff Brown int status; 92053b865412d1982ad1dc0e840898d82527deeb99Jeff Brown pid_t n = waitpid(tid, &status, __WALL | WNOHANG); 93053b865412d1982ad1dc0e840898d82527deeb99Jeff Brown if (n < 0) { 94053b865412d1982ad1dc0e840898d82527deeb99Jeff Brown if(errno == EAGAIN) continue; 95053b865412d1982ad1dc0e840898d82527deeb99Jeff Brown LOG("waitpid failed: %s\n", strerror(errno)); 96053b865412d1982ad1dc0e840898d82527deeb99Jeff Brown return -1; 97053b865412d1982ad1dc0e840898d82527deeb99Jeff Brown } else if (n > 0) { 98053b865412d1982ad1dc0e840898d82527deeb99Jeff Brown XLOG("waitpid: n=%d status=%08x\n", n, status); 99053b865412d1982ad1dc0e840898d82527deeb99Jeff Brown if (WIFSTOPPED(status)) { 100053b865412d1982ad1dc0e840898d82527deeb99Jeff Brown return WSTOPSIG(status); 10113e715b491e876865e752a3a69dd6f347049a488Jeff Brown } else { 102053b865412d1982ad1dc0e840898d82527deeb99Jeff Brown LOG("unexpected waitpid response: n=%d, status=%08x\n", n, status); 103053b865412d1982ad1dc0e840898d82527deeb99Jeff Brown return -1; 10413e715b491e876865e752a3a69dd6f347049a488Jeff Brown } 10513e715b491e876865e752a3a69dd6f347049a488Jeff Brown } 10613e715b491e876865e752a3a69dd6f347049a488Jeff Brown 107053b865412d1982ad1dc0e840898d82527deeb99Jeff Brown if (*total_sleep_time_usec > max_total_sleep_usec) { 108053b865412d1982ad1dc0e840898d82527deeb99Jeff Brown LOG("timed out waiting for tid=%d to die\n", tid); 109053b865412d1982ad1dc0e840898d82527deeb99Jeff Brown return -1; 11013e715b491e876865e752a3a69dd6f347049a488Jeff Brown } 11113e715b491e876865e752a3a69dd6f347049a488Jeff Brown 112053b865412d1982ad1dc0e840898d82527deeb99Jeff Brown /* not ready yet */ 113053b865412d1982ad1dc0e840898d82527deeb99Jeff Brown XLOG("not ready yet\n"); 114053b865412d1982ad1dc0e840898d82527deeb99Jeff Brown usleep(sleep_time_usec); 115053b865412d1982ad1dc0e840898d82527deeb99Jeff Brown *total_sleep_time_usec += sleep_time_usec; 116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 118136dcc5ce628a1ba600a6818e5cb24d5f15eb016Andy McFadden 119053b865412d1982ad1dc0e840898d82527deeb99Jeff Brownvoid wait_for_stop(pid_t tid, int* total_sleep_time_usec) { 12013e715b491e876865e752a3a69dd6f347049a488Jeff Brown siginfo_t si; 121053b865412d1982ad1dc0e840898d82527deeb99Jeff Brown while (TEMP_FAILURE_RETRY(ptrace(PTRACE_GETSIGINFO, tid, 0, &si)) < 0 && errno == ESRCH) { 122053b865412d1982ad1dc0e840898d82527deeb99Jeff Brown if (*total_sleep_time_usec > max_total_sleep_usec) { 123053b865412d1982ad1dc0e840898d82527deeb99Jeff Brown LOG("timed out waiting for tid=%d to stop\n", tid); 12413e715b491e876865e752a3a69dd6f347049a488Jeff Brown break; 12513e715b491e876865e752a3a69dd6f347049a488Jeff Brown } 12613e715b491e876865e752a3a69dd6f347049a488Jeff Brown 127053b865412d1982ad1dc0e840898d82527deeb99Jeff Brown usleep(sleep_time_usec); 128053b865412d1982ad1dc0e840898d82527deeb99Jeff Brown *total_sleep_time_usec += sleep_time_usec; 129136dcc5ce628a1ba600a6818e5cb24d5f15eb016Andy McFadden } 130136dcc5ce628a1ba600a6818e5cb24d5f15eb016Andy McFadden} 131