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