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 <cutils/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 #if !ADB_HOST 92 std::string get_trace_setting_from_prop() { 93 char buf[PROPERTY_VALUE_MAX]; 94 property_get("persist.adb.trace_mask", buf, ""); 95 return std::string(buf); 96 } 97 #endif 98 99 std::string get_trace_setting() { 100 #if ADB_HOST 101 return get_trace_setting_from_env(); 102 #else 103 return get_trace_setting_from_prop(); 104 #endif 105 } 106 107 // Split the space separated list of tags from the trace setting and build the 108 // trace mask from it. note that '1' and 'all' are special cases to enable all 109 // tracing. 110 // 111 // adb's trace setting comes from the ADB_TRACE environment variable, whereas 112 // adbd's comes from the system property persist.adb.trace_mask. 113 static void setup_trace_mask() { 114 const std::string trace_setting = get_trace_setting(); 115 if (trace_setting.empty()) { 116 return; 117 } 118 119 std::unordered_map<std::string, int> trace_flags = { 120 {"1", 0}, 121 {"all", 0}, 122 {"adb", ADB}, 123 {"sockets", SOCKETS}, 124 {"packets", PACKETS}, 125 {"rwx", RWX}, 126 {"usb", USB}, 127 {"sync", SYNC}, 128 {"sysdeps", SYSDEPS}, 129 {"transport", TRANSPORT}, 130 {"jdwp", JDWP}, 131 {"services", SERVICES}, 132 {"auth", AUTH}, 133 {"fdevent", FDEVENT}, 134 {"shell", SHELL}}; 135 136 std::vector<std::string> elements = android::base::Split(trace_setting, " "); 137 for (const auto& elem : elements) { 138 const auto& flag = trace_flags.find(elem); 139 if (flag == trace_flags.end()) { 140 LOG(ERROR) << "Unknown trace flag: " << elem; 141 continue; 142 } 143 144 if (flag->second == 0) { 145 // 0 is used for the special values "1" and "all" that enable all 146 // tracing. 147 adb_trace_mask = ~0; 148 return; 149 } else { 150 adb_trace_mask |= 1 << flag->second; 151 } 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 android::base::InitLogging(argv, &AdbLogger); 167 setup_trace_mask(); 168 169 VLOG(ADB) << adb_version(); 170 } 171 172 void adb_trace_enable(AdbTrace trace_tag) { 173 adb_trace_mask |= (1 << trace_tag); 174 } 175