utility.c revision 053b865412d1982ad1dc0e840898d82527deeb99
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> 2513e715b491e876865e752a3a69dd6f347049a488Jeff Brown#include <cutils/logd.h> 2613e715b491e876865e752a3a69dd6f347049a488Jeff Brown#include <sys/ptrace.h> 27053b865412d1982ad1dc0e840898d82527deeb99Jeff Brown#include <sys/wait.h> 28dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 29dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "utility.h" 30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 31053b865412d1982ad1dc0e840898d82527deeb99Jeff Brownconst int sleep_time_usec = 50000; /* 0.05 seconds */ 32053b865412d1982ad1dc0e840898d82527deeb99Jeff Brownconst int max_total_sleep_usec = 10000000; /* 10 seconds */ 3313e715b491e876865e752a3a69dd6f347049a488Jeff Brown 34053b865412d1982ad1dc0e840898d82527deeb99Jeff Brownvoid _LOG(log_t* log, bool in_tombstone_only, const char *fmt, ...) { 3513e715b491e876865e752a3a69dd6f347049a488Jeff Brown char buf[512]; 3613e715b491e876865e752a3a69dd6f347049a488Jeff Brown 3713e715b491e876865e752a3a69dd6f347049a488Jeff Brown va_list ap; 3813e715b491e876865e752a3a69dd6f347049a488Jeff Brown va_start(ap, fmt); 3913e715b491e876865e752a3a69dd6f347049a488Jeff Brown 40053b865412d1982ad1dc0e840898d82527deeb99Jeff Brown if (log && log->tfd >= 0) { 4113e715b491e876865e752a3a69dd6f347049a488Jeff Brown int len; 4213e715b491e876865e752a3a69dd6f347049a488Jeff Brown vsnprintf(buf, sizeof(buf), fmt, ap); 4313e715b491e876865e752a3a69dd6f347049a488Jeff Brown len = strlen(buf); 44053b865412d1982ad1dc0e840898d82527deeb99Jeff Brown write(log->tfd, buf, len); 4513e715b491e876865e752a3a69dd6f347049a488Jeff Brown } 4613e715b491e876865e752a3a69dd6f347049a488Jeff Brown 47053b865412d1982ad1dc0e840898d82527deeb99Jeff Brown if (!in_tombstone_only && (!log || !log->quiet)) { 4813e715b491e876865e752a3a69dd6f347049a488Jeff Brown __android_log_vprint(ANDROID_LOG_INFO, "DEBUG", fmt, ap); 4913e715b491e876865e752a3a69dd6f347049a488Jeff Brown } 50053b865412d1982ad1dc0e840898d82527deeb99Jeff Brown va_end(ap); 5113e715b491e876865e752a3a69dd6f347049a488Jeff Brown} 52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 53053b865412d1982ad1dc0e840898d82527deeb99Jeff Brownint wait_for_signal(pid_t tid, int* total_sleep_time_usec) { 54053b865412d1982ad1dc0e840898d82527deeb99Jeff Brown for (;;) { 55053b865412d1982ad1dc0e840898d82527deeb99Jeff Brown int status; 56053b865412d1982ad1dc0e840898d82527deeb99Jeff Brown pid_t n = waitpid(tid, &status, __WALL | WNOHANG); 57053b865412d1982ad1dc0e840898d82527deeb99Jeff Brown if (n < 0) { 58053b865412d1982ad1dc0e840898d82527deeb99Jeff Brown if(errno == EAGAIN) continue; 59053b865412d1982ad1dc0e840898d82527deeb99Jeff Brown LOG("waitpid failed: %s\n", strerror(errno)); 60053b865412d1982ad1dc0e840898d82527deeb99Jeff Brown return -1; 61053b865412d1982ad1dc0e840898d82527deeb99Jeff Brown } else if (n > 0) { 62053b865412d1982ad1dc0e840898d82527deeb99Jeff Brown XLOG("waitpid: n=%d status=%08x\n", n, status); 63053b865412d1982ad1dc0e840898d82527deeb99Jeff Brown if (WIFSTOPPED(status)) { 64053b865412d1982ad1dc0e840898d82527deeb99Jeff Brown return WSTOPSIG(status); 6513e715b491e876865e752a3a69dd6f347049a488Jeff Brown } else { 66053b865412d1982ad1dc0e840898d82527deeb99Jeff Brown LOG("unexpected waitpid response: n=%d, status=%08x\n", n, status); 67053b865412d1982ad1dc0e840898d82527deeb99Jeff Brown return -1; 6813e715b491e876865e752a3a69dd6f347049a488Jeff Brown } 6913e715b491e876865e752a3a69dd6f347049a488Jeff Brown } 7013e715b491e876865e752a3a69dd6f347049a488Jeff Brown 71053b865412d1982ad1dc0e840898d82527deeb99Jeff Brown if (*total_sleep_time_usec > max_total_sleep_usec) { 72053b865412d1982ad1dc0e840898d82527deeb99Jeff Brown LOG("timed out waiting for tid=%d to die\n", tid); 73053b865412d1982ad1dc0e840898d82527deeb99Jeff Brown return -1; 7413e715b491e876865e752a3a69dd6f347049a488Jeff Brown } 7513e715b491e876865e752a3a69dd6f347049a488Jeff Brown 76053b865412d1982ad1dc0e840898d82527deeb99Jeff Brown /* not ready yet */ 77053b865412d1982ad1dc0e840898d82527deeb99Jeff Brown XLOG("not ready yet\n"); 78053b865412d1982ad1dc0e840898d82527deeb99Jeff Brown usleep(sleep_time_usec); 79053b865412d1982ad1dc0e840898d82527deeb99Jeff Brown *total_sleep_time_usec += sleep_time_usec; 80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 82136dcc5ce628a1ba600a6818e5cb24d5f15eb016Andy McFadden 83053b865412d1982ad1dc0e840898d82527deeb99Jeff Brownvoid wait_for_stop(pid_t tid, int* total_sleep_time_usec) { 8413e715b491e876865e752a3a69dd6f347049a488Jeff Brown siginfo_t si; 85053b865412d1982ad1dc0e840898d82527deeb99Jeff Brown while (TEMP_FAILURE_RETRY(ptrace(PTRACE_GETSIGINFO, tid, 0, &si)) < 0 && errno == ESRCH) { 86053b865412d1982ad1dc0e840898d82527deeb99Jeff Brown if (*total_sleep_time_usec > max_total_sleep_usec) { 87053b865412d1982ad1dc0e840898d82527deeb99Jeff Brown LOG("timed out waiting for tid=%d to stop\n", tid); 8813e715b491e876865e752a3a69dd6f347049a488Jeff Brown break; 8913e715b491e876865e752a3a69dd6f347049a488Jeff Brown } 9013e715b491e876865e752a3a69dd6f347049a488Jeff Brown 91053b865412d1982ad1dc0e840898d82527deeb99Jeff Brown usleep(sleep_time_usec); 92053b865412d1982ad1dc0e840898d82527deeb99Jeff Brown *total_sleep_time_usec += sleep_time_usec; 93136dcc5ce628a1ba600a6818e5cb24d5f15eb016Andy McFadden } 94136dcc5ce628a1ba600a6818e5cb24d5f15eb016Andy McFadden} 95