From 52d0b67f191319e20272d404659ec2f967d2769c Mon Sep 17 00:00:00 2001 From: Josh Gao Date: Wed, 26 Feb 2020 16:39:20 -0800 Subject: [PATCH] adbd: add runtime-configurable logging. Add some requested logging options that can be turned on at runtime without having to restart adbd. Bug: http://b/141959374 Test: manual Change-Id: Ib97acc6d199e0b91238a6758e18b7cb75f8688d9 --- adb/Android.bp | 1 + adb/adb.cpp | 6 +++ adb/daemon/logging.cpp | 89 ++++++++++++++++++++++++++++++++++++ adb/daemon/logging.h | 33 +++++++++++++ adb/daemon/services.cpp | 4 +- adb/daemon/shell_service.cpp | 5 +- 6 files changed, 135 insertions(+), 3 deletions(-) create mode 100644 adb/daemon/logging.cpp create mode 100644 adb/daemon/logging.h diff --git a/adb/Android.bp b/adb/Android.bp index fea8c7807..50e372793 100644 --- a/adb/Android.bp +++ b/adb/Android.bp @@ -375,6 +375,7 @@ cc_library_static { srcs: libadb_srcs + libadb_linux_srcs + libadb_posix_srcs + [ "daemon/auth.cpp", "daemon/jdwp_service.cpp", + "daemon/logging.cpp", "daemon/adb_wifi.cpp", ], diff --git a/adb/adb.cpp b/adb/adb.cpp index 554a754fd..98db19123 100644 --- a/adb/adb.cpp +++ b/adb/adb.cpp @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -61,6 +62,8 @@ #include #include using namespace std::chrono_literals; + +#include "daemon/logging.h" #endif std::string adb_version() { @@ -312,6 +315,9 @@ static void handle_new_connection(atransport* t, apacket* p) { #if ADB_HOST handle_online(t); #else + ADB_LOG(Connection) << "received CNXN: version=" << p->msg.arg0 << ", maxdata = " << p->msg.arg1 + << ", banner = '" << banner << "'"; + if (t->use_tls) { // We still handshake in TLS mode. If auth_required is disabled, // we'll just not verify the client's certificate. This should be the diff --git a/adb/daemon/logging.cpp b/adb/daemon/logging.cpp new file mode 100644 index 000000000..203c6c73d --- /dev/null +++ b/adb/daemon/logging.cpp @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "daemon/logging.h" + +#include +#include +#include + +#include +#include +#include +#include + +#if defined(__ANDROID__) +struct LogStatus { + bool enabled[static_cast(adb::LogType::COUNT)]; + + bool& operator[](adb::LogType type) { return enabled[static_cast(type)]; } +}; + +using android::base::CachedProperty; +using android::base::NoDestructor; + +static NoDestructor log_mutex; +static NoDestructor log_property GUARDED_BY(log_mutex)("debug.adbd.logging"); +static std::optional cached_log_status GUARDED_BY(log_mutex); + +static NoDestructor persist_log_property + GUARDED_BY(log_mutex)("persist.debug.adbd.logging"); +static std::optional cached_persist_log_status GUARDED_BY(log_mutex); + +static LogStatus ParseLogStatus(std::string_view str) { + LogStatus result = {}; + for (const auto& part : android::base::Split(std::string(str), ",")) { + if (part == "cnxn") { + result[adb::LogType::Connection] = true; + } else if (part == "service") { + result[adb::LogType::Service] = true; + } else if (part == "shell") { + result[adb::LogType::Shell] = true; + } else if (part == "all") { + result[adb::LogType::Connection] = true; + result[adb::LogType::Service] = true; + result[adb::LogType::Shell] = true; + } + } + return result; +} + +static LogStatus GetLogStatus(android::base::CachedProperty* property, + std::optional* cached_status) REQUIRES(log_mutex) { + bool changed; + const char* value = property->Get(&changed); + if (changed || !*cached_status) { + **cached_status = ParseLogStatus(value); + } + return **cached_status; +} + +namespace adb { +bool is_logging_enabled(LogType type) { + std::lock_guard lock(*log_mutex); + return GetLogStatus(log_property.get(), &cached_log_status)[type] || + GetLogStatus(persist_log_property.get(), &cached_persist_log_status)[type]; +} +} // namespace adb + +#else + +namespace adb { +bool is_logging_enabled(LogType type) { + return false; +} +} // namespace adb +#endif diff --git a/adb/daemon/logging.h b/adb/daemon/logging.h new file mode 100644 index 000000000..3e28bef31 --- /dev/null +++ b/adb/daemon/logging.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +namespace adb { +enum class LogType { + Connection, + Service, + Shell, + COUNT, +}; + +bool is_logging_enabled(LogType type); + +#define ADB_LOG(type) ::adb::is_logging_enabled(::adb::LogType::type) && LOG(INFO) + +} // namespace adb diff --git a/adb/daemon/services.cpp b/adb/daemon/services.cpp index 4ec90d27c..6bbf66e8e 100644 --- a/adb/daemon/services.cpp +++ b/adb/daemon/services.cpp @@ -54,10 +54,10 @@ #include "daemon/file_sync_service.h" #include "daemon/framebuffer_service.h" +#include "daemon/logging.h" #include "daemon/restart_service.h" #include "daemon/shell_service.h" - void reconnect_service(unique_fd fd, atransport* t) { WriteFdExactly(fd.get(), "done"); kick_transport(t); @@ -259,6 +259,8 @@ asocket* daemon_service_to_socket(std::string_view name) { } unique_fd daemon_service_to_fd(std::string_view name, atransport* transport) { + ADB_LOG(Service) << "transport " << transport->serial_name() << " opening service " << name; + #if defined(__ANDROID__) && !defined(__ANDROID_RECOVERY__) if (name.starts_with("abb:") || name.starts_with("abb_exec:")) { return execute_abb_command(name); diff --git a/adb/daemon/shell_service.cpp b/adb/daemon/shell_service.cpp index f62032d06..fbfae1e44 100644 --- a/adb/daemon/shell_service.cpp +++ b/adb/daemon/shell_service.cpp @@ -107,6 +107,7 @@ #include "adb_trace.h" #include "adb_unique_fd.h" #include "adb_utils.h" +#include "daemon/logging.h" #include "security_log_tags.h" #include "shell_protocol.h" @@ -760,14 +761,14 @@ void Subprocess::WaitForExit() { D("post waitpid (pid=%d) status=%04x", pid_, status); if (WIFSIGNALED(status)) { exit_code = 0x80 | WTERMSIG(status); - D("subprocess killed by signal %d", WTERMSIG(status)); + ADB_LOG(Shell) << "subprocess " << pid_ << " killed by signal " << WTERMSIG(status); break; } else if (!WIFEXITED(status)) { D("subprocess didn't exit"); break; } else if (WEXITSTATUS(status) >= 0) { exit_code = WEXITSTATUS(status); - D("subprocess exit code = %d", WEXITSTATUS(status)); + ADB_LOG(Shell) << "subprocess " << pid_ << " exited with status " << exit_code; break; } }