Move all logging to use the async safe logging.

Also, add a link to the .clang-format-2 for this directory and clang
format the files that changed.

Bug: 31919199

Test: Boot bullhead.
Test: Run unit tests on bullhead. There are a few that fail, but they
Test: failed before and are not a result of this change.
Change-Id: I3d3b2111f6f6bf8a0d7039295d34d5168c191651
This commit is contained in:
Christopher Ferris 2017-05-03 17:34:29 -07:00
parent c7988b1f68
commit 47dea71b16
11 changed files with 96 additions and 75 deletions

View file

@ -0,0 +1 @@
../.clang-format-2

View file

@ -9,8 +9,16 @@ cc_defaults {
clang: true,
shared_libs: [
"libbase",
"liblog",
],
target: {
android: {
static_libs: ["libasync_safe"],
},
host: {
shared_libs: ["liblog"],
}
},
}
cc_library_shared {

View file

@ -42,11 +42,9 @@ bool HeapWalker::Allocation(uintptr_t begin, uintptr_t end) {
} else {
Range overlap = inserted.first->first;
if (overlap != range) {
ALOGE("range %p-%p overlaps with existing range %p-%p",
reinterpret_cast<void*>(begin),
reinterpret_cast<void*>(end),
reinterpret_cast<void*>(overlap.begin),
reinterpret_cast<void*>(overlap.end));
MEM_ALOGE("range %p-%p overlaps with existing range %p-%p", reinterpret_cast<void*>(begin),
reinterpret_cast<void*>(end), reinterpret_cast<void*>(overlap.begin),
reinterpret_cast<void*>(overlap.end));
}
return false;
}
@ -154,7 +152,7 @@ static bool MapOverPage(void* addr) {
void* ret = mmap(page, page_size, PROT_READ, MAP_ANONYMOUS|MAP_PRIVATE|MAP_FIXED, -1, 0);
if (ret == MAP_FAILED) {
ALOGE("failed to map page at %p: %s", page, strerror(errno));
MEM_ALOGE("failed to map page at %p: %s", page, strerror(errno));
return false;
}
@ -167,7 +165,7 @@ void HeapWalker::HandleSegFault(ScopedSignalHandler& handler, int signal, siginf
handler.reset();
return;
}
ALOGW("failed to read page at %p, signal %d", si->si_addr, signal);
MEM_ALOGW("failed to read page at %p, signal %d", si->si_addr, signal);
if (!MapOverPage(si->si_addr)) {
handler.reset();
}

View file

@ -44,11 +44,11 @@ bool LeakPipe::SendFd(int sock, int fd) {
int ret = sendmsg(sock, &hdr, 0);
if (ret < 0) {
ALOGE("failed to send fd: %s", strerror(errno));
MEM_ALOGE("failed to send fd: %s", strerror(errno));
return false;
}
if (ret == 0) {
ALOGE("eof when sending fd");
MEM_ALOGE("eof when sending fd");
return false;
}
@ -71,17 +71,17 @@ int LeakPipe::ReceiveFd(int sock) {
int ret = recvmsg(sock, &hdr, 0);
if (ret < 0) {
ALOGE("failed to receive fd: %s", strerror(errno));
MEM_ALOGE("failed to receive fd: %s", strerror(errno));
return -1;
}
if (ret == 0) {
ALOGE("eof when receiving fd");
MEM_ALOGE("eof when receiving fd");
return -1;
}
struct cmsghdr* cmsg = CMSG_FIRSTHDR(&hdr);
if (cmsg == NULL || cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
ALOGE("missing fd while receiving fd");
MEM_ALOGE("missing fd while receiving fd");
return -1;
}

View file

@ -36,7 +36,7 @@ class LeakPipe {
LeakPipe() {
int ret = socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, sv_);
if (ret < 0) {
LOG_ALWAYS_FATAL("failed to create socketpair: %s", strerror(errno));
MEM_LOG_ALWAYS_FATAL("failed to create socketpair: %s", strerror(errno));
}
}
@ -105,10 +105,10 @@ class LeakPipe {
bool Send(const T& value) {
ssize_t ret = TEMP_FAILURE_RETRY(write(fd_, &value, sizeof(T)));
if (ret < 0) {
ALOGE("failed to send value: %s", strerror(errno));
MEM_ALOGE("failed to send value: %s", strerror(errno));
return false;
} else if (static_cast<size_t>(ret) != sizeof(T)) {
ALOGE("eof while writing value");
MEM_ALOGE("eof while writing value");
return false;
}
@ -124,10 +124,10 @@ class LeakPipe {
ssize_t ret = TEMP_FAILURE_RETRY(write(fd_, vector.data(), size));
if (ret < 0) {
ALOGE("failed to send vector: %s", strerror(errno));
MEM_ALOGE("failed to send vector: %s", strerror(errno));
return false;
} else if (static_cast<size_t>(ret) != size) {
ALOGE("eof while writing vector");
MEM_ALOGE("eof while writing vector");
return false;
}
@ -143,10 +143,10 @@ class LeakPipe {
bool Receive(T* value) {
ssize_t ret = TEMP_FAILURE_RETRY(read(fd_, reinterpret_cast<void*>(value), sizeof(T)));
if (ret < 0) {
ALOGE("failed to receive value: %s", strerror(errno));
MEM_ALOGE("failed to receive value: %s", strerror(errno));
return false;
} else if (static_cast<size_t>(ret) != sizeof(T)) {
ALOGE("eof while receiving value");
MEM_ALOGE("eof while receiving value");
return false;
}
@ -166,10 +166,10 @@ class LeakPipe {
while (size > 0) {
ssize_t ret = TEMP_FAILURE_RETRY(read(fd_, ptr, size));
if (ret < 0) {
ALOGE("failed to send vector: %s", strerror(errno));
MEM_ALOGE("failed to send vector: %s", strerror(errno));
return false;
} else if (ret == 0) {
ALOGE("eof while reading vector");
MEM_ALOGE("eof while reading vector");
return false;
}
size -= ret;

View file

@ -78,51 +78,49 @@ static void HeapIterate(const Mapping& heap_mapping,
bool MemUnreachable::CollectAllocations(const allocator::vector<ThreadInfo>& threads,
const allocator::vector<Mapping>& mappings) {
ALOGI("searching process %d for allocations", pid_);
MEM_ALOGI("searching process %d for allocations", pid_);
allocator::vector<Mapping> heap_mappings{mappings};
allocator::vector<Mapping> anon_mappings{mappings};
allocator::vector<Mapping> globals_mappings{mappings};
allocator::vector<Mapping> stack_mappings{mappings};
if (!ClassifyMappings(mappings, heap_mappings, anon_mappings,
globals_mappings, stack_mappings)) {
if (!ClassifyMappings(mappings, heap_mappings, anon_mappings, globals_mappings, stack_mappings)) {
return false;
}
for (auto it = heap_mappings.begin(); it != heap_mappings.end(); it++) {
ALOGV("Heap mapping %" PRIxPTR "-%" PRIxPTR " %s", it->begin, it->end, it->name);
HeapIterate(*it, [&](uintptr_t base, size_t size) {
heap_walker_.Allocation(base, base + size);
});
MEM_ALOGV("Heap mapping %" PRIxPTR "-%" PRIxPTR " %s", it->begin, it->end, it->name);
HeapIterate(*it,
[&](uintptr_t base, size_t size) { heap_walker_.Allocation(base, base + size); });
}
for (auto it = anon_mappings.begin(); it != anon_mappings.end(); it++) {
ALOGV("Anon mapping %" PRIxPTR "-%" PRIxPTR " %s", it->begin, it->end, it->name);
MEM_ALOGV("Anon mapping %" PRIxPTR "-%" PRIxPTR " %s", it->begin, it->end, it->name);
heap_walker_.Allocation(it->begin, it->end);
}
for (auto it = globals_mappings.begin(); it != globals_mappings.end(); it++) {
ALOGV("Globals mapping %" PRIxPTR "-%" PRIxPTR " %s", it->begin, it->end, it->name);
MEM_ALOGV("Globals mapping %" PRIxPTR "-%" PRIxPTR " %s", it->begin, it->end, it->name);
heap_walker_.Root(it->begin, it->end);
}
for (auto thread_it = threads.begin(); thread_it != threads.end(); thread_it++) {
for (auto it = stack_mappings.begin(); it != stack_mappings.end(); it++) {
if (thread_it->stack.first >= it->begin && thread_it->stack.first <= it->end) {
ALOGV("Stack %" PRIxPTR "-%" PRIxPTR " %s", thread_it->stack.first, it->end, it->name);
MEM_ALOGV("Stack %" PRIxPTR "-%" PRIxPTR " %s", thread_it->stack.first, it->end, it->name);
heap_walker_.Root(thread_it->stack.first, it->end);
}
}
heap_walker_.Root(thread_it->regs);
}
ALOGI("searching done");
MEM_ALOGI("searching done");
return true;
}
bool MemUnreachable::GetUnreachableMemory(allocator::vector<Leak>& leaks,
size_t limit, size_t* num_leaks, size_t* leak_bytes) {
ALOGI("sweeping process %d for unreachable memory", pid_);
MEM_ALOGI("sweeping process %d for unreachable memory", pid_);
leaks.clear();
if (!heap_walker_.DetectLeaks()) {
@ -133,9 +131,9 @@ bool MemUnreachable::GetUnreachableMemory(allocator::vector<Leak>& leaks,
allocator::vector<Range> leaked1{allocator_};
heap_walker_.Leaked(leaked1, 0, num_leaks, leak_bytes);
ALOGI("sweeping done");
MEM_ALOGI("sweeping done");
ALOGI("folding related leaks");
MEM_ALOGI("folding related leaks");
LeakFolding folding(allocator_, heap_walker_);
if (!folding.FoldLeaks()) {
@ -188,7 +186,7 @@ bool MemUnreachable::GetUnreachableMemory(allocator::vector<Leak>& leaks,
std::min(leak->size, Leak::contents_length));
}
ALOGI("folding done");
MEM_ALOGI("folding done");
std::sort(leaks.begin(), leaks.end(), [](const Leak& a, const Leak& b) {
return a.total_size > b.total_size;
@ -276,7 +274,7 @@ bool GetUnreachableMemory(UnreachableMemoryInfo& info, size_t limit) {
/////////////////////////////////////////////
// Collection thread
/////////////////////////////////////////////
ALOGI("collecting thread info for process %d...", parent_pid);
MEM_ALOGI("collecting thread info for process %d...", parent_pid);
ThreadCapture thread_capture(parent_pid, heap);
allocator::vector<ThreadInfo> thread_info(heap);
@ -351,7 +349,7 @@ bool GetUnreachableMemory(UnreachableMemoryInfo& info, size_t limit) {
} else {
// Nothing left to do in the collection thread, return immediately,
// releasing all the captured threads.
ALOGI("collection thread done");
MEM_ALOGI("collection thread done");
return 0;
}
}};
@ -397,10 +395,10 @@ bool GetUnreachableMemory(UnreachableMemoryInfo& info, size_t limit) {
return false;
}
ALOGI("unreachable memory detection done");
ALOGE("%zu bytes in %zu allocation%s unreachable out of %zu bytes in %zu allocation%s",
info.leak_bytes, info.num_leaks, plural(info.num_leaks),
info.allocation_bytes, info.num_allocations, plural(info.num_allocations));
MEM_ALOGI("unreachable memory detection done");
MEM_ALOGE("%zu bytes in %zu allocation%s unreachable out of %zu bytes in %zu allocation%s",
info.leak_bytes, info.num_leaks, plural(info.num_leaks), info.allocation_bytes,
info.num_allocations, plural(info.num_allocations));
return true;
}
@ -517,7 +515,7 @@ bool LogUnreachableMemory(bool log_contents, size_t limit) {
}
for (auto it = info.leaks.begin(); it != info.leaks.end(); it++) {
ALOGE("%s", it->ToString(log_contents).c_str());
MEM_ALOGE("%s", it->ToString(log_contents).c_str());
}
return true;
}

View file

@ -70,7 +70,7 @@ PtracerThread::PtracerThread(const std::function<int()>& func) :
child_pid_(0) {
stack_ = std::make_unique<Stack>(PTHREAD_STACK_MIN);
if (stack_->top() == nullptr) {
LOG_ALWAYS_FATAL("failed to mmap child stack: %s", strerror(errno));
MEM_LOG_ALWAYS_FATAL("failed to mmap child stack: %s", strerror(errno));
}
func_ = std::function<int()>{[&, func]() -> int {
@ -102,7 +102,7 @@ bool PtracerThread::Start() {
CLONE_VM|CLONE_FS|CLONE_FILES/*|CLONE_UNTRACED*/,
reinterpret_cast<void*>(&func_));
if (child_pid_ < 0) {
ALOGE("failed to clone child: %s", strerror(errno));
MEM_ALOGE("failed to clone child: %s", strerror(errno));
return false;
}
@ -120,7 +120,7 @@ int PtracerThread::Join() {
int status;
int ret = TEMP_FAILURE_RETRY(waitpid(child_pid_, &status, __WALL));
if (ret < 0) {
ALOGE("waitpid %d failed: %s", child_pid_, strerror(errno));
MEM_ALOGE("waitpid %d failed: %s", child_pid_, strerror(errno));
return -1;
}
@ -131,7 +131,7 @@ int PtracerThread::Join() {
} else if (WIFSIGNALED(status)) {
return -WTERMSIG(status);
} else {
ALOGE("unexpected status %x", status);
MEM_ALOGE("unexpected status %x", status);
return -1;
}
}

View file

@ -26,7 +26,7 @@ class ScopedPipe {
ScopedPipe() : pipefd_{-1, -1} {
int ret = pipe2(pipefd_, O_CLOEXEC);
if (ret < 0) {
LOG_ALWAYS_FATAL("failed to open pipe");
MEM_LOG_ALWAYS_FATAL("failed to open pipe");
}
}
~ScopedPipe() {

View file

@ -37,22 +37,18 @@ class ScopedSignalHandler {
template <class F>
void install(int signal, F&& f) {
LOG_ALWAYS_FATAL_IF(signal_ != -1, "ScopedSignalHandler already installed");
MEM_LOG_ALWAYS_FATAL_IF(signal_ != -1, "ScopedSignalHandler already installed");
handler_ = SignalFn(std::allocator_arg, allocator_,
[=](int signal, siginfo_t* si, void* uctx) {
f(*this, signal, si, uctx);
});
[=](int signal, siginfo_t* si, void* uctx) { f(*this, signal, si, uctx); });
struct sigaction act{};
act.sa_sigaction = [](int signal, siginfo_t* si, void* uctx) {
handler_(signal, si, uctx);
};
struct sigaction act {};
act.sa_sigaction = [](int signal, siginfo_t* si, void* uctx) { handler_(signal, si, uctx); };
act.sa_flags = SA_SIGINFO;
int ret = sigaction(signal, &act, &old_act_);
if (ret < 0) {
LOG_ALWAYS_FATAL("failed to install segfault handler: %s", strerror(errno));
MEM_LOG_ALWAYS_FATAL("failed to install segfault handler: %s", strerror(errno));
}
signal_ = signal;
@ -62,7 +58,7 @@ class ScopedSignalHandler {
if (signal_ != -1) {
int ret = sigaction(signal_, &old_act_, NULL);
if (ret < 0) {
ALOGE("failed to uninstall segfault handler");
MEM_ALOGE("failed to uninstall segfault handler");
}
handler_ = SignalFn{};
signal_ = -1;

View file

@ -110,7 +110,7 @@ bool ThreadCaptureImpl::ListThreads(TidList& tids) {
android::base::unique_fd fd(open(path, O_CLOEXEC | O_DIRECTORY | O_RDONLY));
if (fd == -1) {
ALOGE("failed to open %s: %s", path, strerror(errno));
MEM_ALOGE("failed to open %s: %s", path, strerror(errno));
return false;
}
@ -126,7 +126,7 @@ bool ThreadCaptureImpl::ListThreads(TidList& tids) {
do {
nread = syscall(SYS_getdents64, fd.get(), dirent_buf, sizeof(dirent_buf));
if (nread < 0) {
ALOGE("failed to get directory entries from %s: %s", path, strerror(errno));
MEM_ALOGE("failed to get directory entries from %s: %s", path, strerror(errno));
return false;
} else if (nread > 0) {
ssize_t off = 0;
@ -177,8 +177,7 @@ bool ThreadCaptureImpl::CaptureThreads() {
void ThreadCaptureImpl::PtraceDetach(pid_t tid, unsigned int signal) {
void* sig_ptr = reinterpret_cast<void*>(static_cast<uintptr_t>(signal));
if (ptrace(PTRACE_DETACH, tid, NULL, sig_ptr) < 0 && errno != ESRCH) {
ALOGE("failed to detach from thread %d of process %d: %s", tid, pid_,
strerror(errno));
MEM_ALOGE("failed to detach from thread %d of process %d: %s", tid, pid_, strerror(errno));
}
}
@ -187,8 +186,7 @@ void ThreadCaptureImpl::PtraceDetach(pid_t tid, unsigned int signal) {
int ThreadCaptureImpl::PtraceAttach(pid_t tid) {
int ret = ptrace(PTRACE_SEIZE, tid, NULL, NULL);
if (ret < 0) {
ALOGE("failed to attach to thread %d of process %d: %s", tid, pid_,
strerror(errno));
MEM_ALOGE("failed to attach to thread %d of process %d: %s", tid, pid_, strerror(errno));
return -1;
}
@ -200,8 +198,7 @@ int ThreadCaptureImpl::PtraceAttach(pid_t tid) {
if (errno == ESRCH) {
return 0;
} else {
ALOGE("failed to interrupt thread %d of process %d: %s", tid, pid_,
strerror(errno));
MEM_ALOGE("failed to interrupt thread %d of process %d: %s", tid, pid_, strerror(errno));
PtraceDetach(tid, 0);
return -1;
}
@ -219,8 +216,7 @@ bool ThreadCaptureImpl::PtraceThreadInfo(pid_t tid, ThreadInfo& thread_info) {
iovec.iov_len = sizeof(regs);
if (ptrace(PTRACE_GETREGSET, tid, reinterpret_cast<void*>(NT_PRSTATUS), &iovec)) {
ALOGE("ptrace getregset for thread %d of process %d failed: %s",
tid, pid_, strerror(errno));
MEM_ALOGE("ptrace getregset for thread %d of process %d failed: %s", tid, pid_, strerror(errno));
return false;
}
@ -258,15 +254,13 @@ int ThreadCaptureImpl::CaptureThread(pid_t tid) {
int status = 0;
if (TEMP_FAILURE_RETRY(waitpid(tid, &status, __WALL)) < 0) {
ALOGE("failed to wait for pause of thread %d of process %d: %s", tid, pid_,
strerror(errno));
MEM_ALOGE("failed to wait for pause of thread %d of process %d: %s", tid, pid_, strerror(errno));
PtraceDetach(tid, 0);
return -1;
}
if (!WIFSTOPPED(status)) {
ALOGE("thread %d of process %d was not paused after waitpid, killed?",
tid, pid_);
MEM_ALOGE("thread %d of process %d was not paused after waitpid, killed?", tid, pid_);
return 0;
}
@ -285,8 +279,8 @@ int ThreadCaptureImpl::CaptureThread(pid_t tid) {
// normal ptrace interrupt stop
break;
default:
ALOGE("unexpected signal %d with PTRACE_EVENT_STOP for thread %d of process %d",
signal, tid, pid_);
MEM_ALOGE("unexpected signal %d with PTRACE_EVENT_STOP for thread %d of process %d", signal,
tid, pid_);
return -1;
}
} else {

View file

@ -19,6 +19,32 @@
#define LOG_TAG "libmemunreachable"
#if defined(__ANDROID__)
#include <async_safe/log.h>
#define MEM_ALOGE(...) async_safe_format_log(ANDROID_LOG_ERROR, LOG_TAG, ##__VA_ARGS__)
#define MEM_ALOGW(...) async_safe_format_log(ANDROID_LOG_WARN, LOG_TAG, ##__VA_ARGS__)
#define MEM_ALOGI(...) async_safe_format_log(ANDROID_LOG_INFO, LOG_TAG, ##__VA_ARGS__)
#define MEM_ALOGV(...) async_safe_format_log(ANDROID_LOG_VERBOSE, LOG_TAG, ##__VA_ARGS__)
#define MEM_LOG_ALWAYS_FATAL(...) async_safe_fatal(__VA_ARGS__)
#define MEM_LOG_ALWAYS_FATAL_IF(cond, ...) \
((__predict_false(cond)) ? async_safe_fatal(__VA_ARGS__) : (void)0)
#else
#include <log/log.h>
#define MEM_ALOGW ALOGW
#define MEM_ALOGE ALOGE
#define MEM_ALOGV ALOGV
#define MEM_ALOGI ALOGI
#define MEM_LOG_ALWAYS_FATAL LOG_ALWAYS_FATAL
#define MEM_LOG_ALWAYS_FATAL_IF LOG_ALWAYS_FATAL_IF
#endif
#endif // LIBMEMUNREACHABLE_LOG_H_