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