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 #include "sysdeps.h" 18 #include "adb_trace.h" 19 20 #include <string> 21 #include <unordered_map> 22 #include <vector> 23 24 #include <android-base/logging.h> 25 #include <android-base/strings.h> 26 27 #include "adb.h" 28 29 #if !ADB_HOST 30 #include <android-base/properties.h> 31 #endif 32 33 #if !ADB_HOST 34 const char* adb_device_banner = "device"; 35 static android::base::LogdLogger gLogdLogger; 36 #else 37 const char* adb_device_banner = "host"; 38 #endif 39 40 void AdbLogger(android::base::LogId id, android::base::LogSeverity severity, 41 const char* tag, const char* file, unsigned int line, 42 const char* message) { 43 android::base::StderrLogger(id, severity, tag, file, line, message); 44 #if !ADB_HOST 45 // Only print logs of INFO or higher to logcat, so that `adb logcat` with adbd tracing on 46 // doesn't result in exponential logging. 47 if (severity >= android::base::INFO) { 48 gLogdLogger(id, severity, tag, file, line, message); 49 } 50 #endif 51 } 52 53 54 #if !ADB_HOST 55 static std::string get_log_file_name() { 56 struct tm now; 57 time_t t; 58 tzset(); 59 time(&t); 60 localtime_r(&t, &now); 61 62 char timestamp[PATH_MAX]; 63 strftime(timestamp, sizeof(timestamp), "%Y-%m-%d-%H-%M-%S", &now); 64 65 return android::base::StringPrintf("/data/adb/adb-%s-%d", timestamp, 66 getpid()); 67 } 68 69 void start_device_log(void) { 70 int fd = unix_open(get_log_file_name().c_str(), 71 O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, 0640); 72 if (fd == -1) { 73 return; 74 } 75 76 // Redirect stdout and stderr to the log file. 77 dup2(fd, STDOUT_FILENO); 78 dup2(fd, STDERR_FILENO); 79 fprintf(stderr, "--- adb starting (pid %d) ---\n", getpid()); 80 unix_close(fd); 81 } 82 #endif 83 84 int adb_trace_mask; 85 86 std::string get_trace_setting_from_env() { 87 const char* setting = getenv("ADB_TRACE"); 88 if (setting == nullptr) { 89 setting = ""; 90 } 91 92 return std::string(setting); 93 } 94 95 std::string get_trace_setting() { 96 #if ADB_HOST 97 return get_trace_setting_from_env(); 98 #else 99 return android::base::GetProperty("persist.adb.trace_mask", ""); 100 #endif 101 } 102 103 // Split the space separated list of tags from the trace setting and build the 104 // trace mask from it. note that '1' and 'all' are special cases to enable all 105 // tracing. 106 // 107 // adb's trace setting comes from the ADB_TRACE environment variable, whereas 108 // adbd's comes from the system property persist.adb.trace_mask. 109 static void setup_trace_mask() { 110 const std::string trace_setting = get_trace_setting(); 111 if (trace_setting.empty()) { 112 return; 113 } 114 115 std::unordered_map<std::string, int> trace_flags = { 116 {"1", -1}, 117 {"all", -1}, 118 {"adb", ADB}, 119 {"sockets", SOCKETS}, 120 {"packets", PACKETS}, 121 {"rwx", RWX}, 122 {"usb", USB}, 123 {"sync", SYNC}, 124 {"sysdeps", SYSDEPS}, 125 {"transport", TRANSPORT}, 126 {"jdwp", JDWP}, 127 {"services", SERVICES}, 128 {"auth", AUTH}, 129 {"fdevent", FDEVENT}, 130 {"shell", SHELL}}; 131 132 std::vector<std::string> elements = android::base::Split(trace_setting, " "); 133 for (const auto& elem : elements) { 134 const auto& flag = trace_flags.find(elem); 135 if (flag == trace_flags.end()) { 136 LOG(ERROR) << "Unknown trace flag: " << elem; 137 continue; 138 } 139 140 if (flag->second == -1) { 141 // -1 is used for the special values "1" and "all" that enable all 142 // tracing. 143 adb_trace_mask = ~0; 144 break; 145 } else { 146 adb_trace_mask |= 1 << flag->second; 147 } 148 } 149 150 if (adb_trace_mask != 0) { 151 android::base::SetMinimumLogSeverity(android::base::VERBOSE); 152 } 153 } 154 155 void adb_trace_init(char** argv) { 156 #if !ADB_HOST 157 // Don't open log file if no tracing, since this will block 158 // the crypto unmount of /data 159 if (!get_trace_setting().empty()) { 160 if (unix_isatty(STDOUT_FILENO) == 0) { 161 start_device_log(); 162 } 163 } 164 #endif 165 166 #if ADB_HOST && !defined(_WIN32) 167 // adb historically ignored $ANDROID_LOG_TAGS but passed it through to logcat. 168 // If set, move it out of the way so that libbase logging doesn't try to parse it. 169 std::string log_tags; 170 char* ANDROID_LOG_TAGS = getenv("ANDROID_LOG_TAGS"); 171 if (ANDROID_LOG_TAGS) { 172 log_tags = ANDROID_LOG_TAGS; 173 unsetenv("ANDROID_LOG_TAGS"); 174 } 175 #endif 176 177 android::base::InitLogging(argv, &AdbLogger); 178 179 #if ADB_HOST && !defined(_WIN32) 180 // Put $ANDROID_LOG_TAGS back so we can pass it to logcat. 181 if (!log_tags.empty()) setenv("ANDROID_LOG_TAGS", log_tags.c_str(), 1); 182 #endif 183 184 setup_trace_mask(); 185 186 VLOG(ADB) << adb_version(); 187 } 188 189 void adb_trace_enable(AdbTrace trace_tag) { 190 adb_trace_mask |= (1 << trace_tag); 191 } 192