blob: 04e6c17bd7f529583c1a9c87fbd1bd5b267428f5 [file] [log] [blame]
Elly Jones03cd6d72012-06-11 13:04:28 -04001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Alex Vakulenko262be3f2014-07-30 15:25:50 -07005#include "debugd/src/log_tool.h"
Elly Jones03cd6d72012-06-11 13:04:28 -04006
Ben Chana0011d82014-05-13 00:19:29 -07007#include <vector>
8
Ben Chanf6cd93a2012-10-14 19:37:00 -07009#include <glib.h>
10
11#include <base/base64.h>
Ben Chancd8fda42014-09-05 08:21:06 -070012#include <base/files/file_util.h>
Elly Jones03cd6d72012-06-11 13:04:28 -040013#include <base/logging.h>
Ben Chan9953a592014-02-05 23:32:00 -080014#include <base/strings/string_split.h>
15#include <base/strings/string_util.h>
Elly Jones03cd6d72012-06-11 13:04:28 -040016
Alex Vakulenko262be3f2014-07-30 15:25:50 -070017#include "debugd/src/anonymizer_tool.h"
18#include "debugd/src/process_with_output.h"
Elly Jones03cd6d72012-06-11 13:04:28 -040019
20namespace debugd {
21
22const char *kShell = "/bin/sh";
Elly Fong-Jones215b5622013-03-20 14:32:18 -040023const char *kDebugfsGroup = "debugfs-access";
Elly Jones03cd6d72012-06-11 13:04:28 -040024
25using std::string;
26using std::vector;
27
28typedef vector<string> Strings;
29
Ben Chanf6cd93a2012-10-14 19:37:00 -070030// Returns |value| if |value| is a valid UTF-8 string or a base64-encoded
31// string of |value| otherwise.
32string EnsureUTF8String(const string& value) {
Ben Chanc93d7582014-05-21 22:53:43 -070033 if (base::IsStringUTF8(value))
Ben Chanf6cd93a2012-10-14 19:37:00 -070034 return value;
35
36 gchar* base64_value = g_base64_encode(
37 reinterpret_cast<const guchar*>(value.c_str()), value.length());
38 if (base64_value) {
39 string encoded_value = "<base64>: ";
40 encoded_value += base64_value;
41 g_free(base64_value);
42 return encoded_value;
43 }
44 return "<invalid>";
45}
46
Elly Fong-Jonesd9a16cd2012-11-12 16:09:49 -050047struct Log {
48 const char *name;
49 const char *command;
50 const char *user;
51 const char *group;
52};
53
Elly Fong-Jones57f018c2012-10-08 14:22:01 -040054// TODO(ellyjones): sandbox. crosbug.com/35122
Elly Fong-Jonesd9a16cd2012-11-12 16:09:49 -050055string Run(const Log& log) {
Elly Jones03cd6d72012-06-11 13:04:28 -040056 string output;
57 ProcessWithOutput p;
Elly Fong-Jonesd9a16cd2012-11-12 16:09:49 -050058 string tailed_cmdline = std::string(log.command) + " | tail -c 256K";
59 if (log.user && log.group)
60 p.SandboxAs(log.user, log.group);
Elly Jones03cd6d72012-06-11 13:04:28 -040061 if (!p.Init())
62 return "<not available>";
63 p.AddArg(kShell);
64 p.AddStringOption("-c", tailed_cmdline);
65 if (p.Run())
66 return "<not available>";
67 p.GetOutput(&output);
68 if (!output.size())
69 return "<empty>";
Ben Chanf6cd93a2012-10-14 19:37:00 -070070 return EnsureUTF8String(output);
Elly Jones03cd6d72012-06-11 13:04:28 -040071}
72
Elly Jones533c7c42012-08-10 15:07:05 -040073static const Log common_logs[] = {
Elly Jones03cd6d72012-06-11 13:04:28 -040074 { "CLIENT_ID", "/bin/cat '/home/chronos/Consent To Send Stats'" },
75 { "LOGDATE", "/bin/date" },
76 { "Xorg.0.log", "/bin/cat /var/log/Xorg.0.log" },
Elly Jones03cd6d72012-06-11 13:04:28 -040077 { "bios_info", "/bin/cat /var/log/bios_info.txt" },
Vadim Bendebury64aeeed2013-09-16 13:16:49 -070078 { "bios_log",
79 "/bin/cat /sys/firmware/log "
80 "/proc/device-tree/chosen/ap-console-buffer 2> /dev/null" },
Stefan Reinauer4393fa72012-10-18 11:08:09 -070081 { "bios_times", "/bin/cat /var/log/bios_times.txt" },
Elly Jones03cd6d72012-06-11 13:04:28 -040082 { "board-specific",
83 "/usr/share/userfeedback/scripts/get_board_specific_info" },
Elly Jones03cd6d72012-06-11 13:04:28 -040084 { "chrome_system_log", "/bin/cat /var/log/chrome/chrome" },
Stefan Reinauer48f883d2014-08-22 14:31:58 -070085 { "console-ramoops", "/bin/cat /dev/pstore/console-ramoops 2> /dev/null" },
Elly Jones03cd6d72012-06-11 13:04:28 -040086 { "cpu", "/usr/bin/uname -p" },
87 { "cpuinfo", "/bin/cat /proc/cpuinfo" },
Elly Jones03cd6d72012-06-11 13:04:28 -040088 { "dmesg", "/bin/dmesg" },
89 { "ec_info", "/bin/cat /var/log/ec_info.txt" },
Stefan Reinauer4393fa72012-10-18 11:08:09 -070090 { "eventlog", "/bin/cat /var/log/eventlog.txt" },
Elly Fong-Jones215b5622013-03-20 14:32:18 -040091 {
92 "exynos_gem_objects",
Yuly Novikov13ece852013-07-11 17:19:10 -040093 "/bin/cat /sys/kernel/debug/dri/0/exynos_gem_objects 2> /dev/null",
Elly Fong-Jones215b5622013-03-20 14:32:18 -040094 SandboxedProcess::kDefaultUser,
95 kDebugfsGroup
96 },
Elly Jones03cd6d72012-06-11 13:04:28 -040097 { "font_info", "/usr/share/userfeedback/scripts/font_info" },
98 { "hardware_class", "/usr/bin/crossystem hwid" },
99 { "hostname", "/bin/hostname" },
100 { "hw_platform", "/usr/bin/uname -i" },
Elly Fong-Jones215b5622013-03-20 14:32:18 -0400101 {
102 "i915_gem_gtt",
Yuly Novikov13ece852013-07-11 17:19:10 -0400103 "/bin/cat /sys/kernel/debug/dri/0/i915_gem_gtt 2> /dev/null",
Elly Fong-Jones215b5622013-03-20 14:32:18 -0400104 SandboxedProcess::kDefaultUser,
105 kDebugfsGroup
106 },
107 {
108 "i915_gem_objects",
Yuly Novikov13ece852013-07-11 17:19:10 -0400109 "/bin/cat /sys/kernel/debug/dri/0/i915_gem_objects 2> /dev/null",
Elly Fong-Jones215b5622013-03-20 14:32:18 -0400110 SandboxedProcess::kDefaultUser,
111 kDebugfsGroup
112 },
113 {
114 "i915_error_state",
Yuly Novikov4ac12fb2013-07-18 20:08:44 -0400115 "/usr/bin/xz -c /sys/kernel/debug/dri/0/i915_error_state 2> /dev/null",
Elly Fong-Jones215b5622013-03-20 14:32:18 -0400116 SandboxedProcess::kDefaultUser,
117 kDebugfsGroup,
118 },
Daniel Erat982ab4b2014-04-09 07:32:38 -0700119 { "ifconfig", "/bin/ifconfig -a" },
Stefan Reinauer48f883d2014-08-22 14:31:58 -0700120 { "kernel-crashes",
121 "/bin/cat /var/spool/crash/kernel.*.kcrash 2> /dev/null" },
Elly Jones03cd6d72012-06-11 13:04:28 -0400122 { "lsmod", "lsmod" },
123 { "lspci", "/usr/sbin/lspci" },
124 { "lsusb", "lsusb" },
Yuly Novikov13ece852013-07-11 17:19:10 -0400125 {
126 "mali_memory",
Dominik Behr4765e6d2013-08-26 16:34:08 -0700127 "/bin/cat /sys/class/misc/mali0/device/memory 2> /dev/null"
Yuly Novikov13ece852013-07-11 17:19:10 -0400128 },
Elly Jones03cd6d72012-06-11 13:04:28 -0400129 { "meminfo", "cat /proc/meminfo" },
130 { "memory_spd_info", "/bin/cat /var/log/memory_spd_info.txt" },
Kees Cooka8f3e7e2012-11-19 14:16:01 -0800131 { "mount-encrypted", "/bin/cat /var/log/mount-encrypted.log" },
Darin Petkov54743582012-12-10 14:18:32 +0100132 { "net-diags.net.log", "/bin/cat /var/log/net-diags.net.log" },
Wade Guthrie67b672e2012-11-14 13:14:31 -0800133 { "netlog", "/usr/share/userfeedback/scripts/getmsgs --last '2 hours'"
134 " /var/log/net.log" },
henryhsufa6daa12014-09-24 13:26:30 +0800135 {
136 "nvmap_iovmm",
137 "/bin/cat /sys/kernel/debug/nvmap/iovmm/allocations 2> /dev/null",
138 SandboxedProcess::kDefaultUser,
139 kDebugfsGroup,
140 },
Vincent Palatinc64af9d2013-08-05 16:34:10 -0700141 { "platform_info", "/bin/cat /var/log/platform_info.txt" },
Daniel Erat9b58b6d2013-04-30 14:58:56 -0700142 { "power_supply_info", "/usr/bin/power_supply_info" },
Elly Jones03cd6d72012-06-11 13:04:28 -0400143 { "powerd.LATEST", "/bin/cat /var/log/power_manager/powerd.LATEST" },
Daniel Erat546c3882013-11-22 12:46:01 -0800144 { "powerd.PREVIOUS", "/bin/cat /var/log/power_manager/powerd.PREVIOUS" },
Daniel Erat93da9a12012-12-06 14:14:17 -0800145 { "powerd.out", "/bin/cat /var/log/powerd.out" },
Elly Jones03cd6d72012-06-11 13:04:28 -0400146 // Changed from 'ps ux' to 'ps aux' since we're running as debugd, not chronos
147 { "ps", "/bin/ps aux" },
Puthikorn Voravootivat6de5e122013-12-06 11:43:13 -0800148 { "storage_info", "/bin/cat /var/log/storage_info.txt" },
Elly Jones03cd6d72012-06-11 13:04:28 -0400149 { "syslog", "/usr/share/userfeedback/scripts/getmsgs --last '2 hours'"
Elly Jonesf8a67ee2012-06-19 13:48:38 -0400150 " /var/log/messages" },
Elly Fong-Jonesb4f49c42013-02-28 13:45:26 -0500151 { "tlsdate", "/bin/cat /var/log/tlsdate.log" },
Elly Jones03cd6d72012-06-11 13:04:28 -0400152 { "touchpad", "/opt/google/touchpad/tpcontrol status" },
Chung-yih Wang4b876142014-04-30 17:01:49 +0800153 { "touchpad_activity", "/opt/google/input/cmt_feedback alt" },
Andrew de los Reyesc060c342013-04-10 13:46:30 -0700154 { "touch_fw_version", "grep -E"
155 " 'synaptics: Touchpad model|chromeos-touch-[a-z]*-update'"
156 " /var/log/messages | tail -n 20" },
Elly Jones03cd6d72012-06-11 13:04:28 -0400157 { "ui_log", "/usr/share/userfeedback/scripts/get_log /var/log/ui/ui.LATEST" },
158 { "uname", "/bin/uname -a" },
159 { "update_engine.log", "cat $(ls -1tr /var/log/update_engine | tail -5 | sed"
Elly Jonesd31aee22012-07-02 11:09:10 -0400160 " s.^./var/log/update_engine/.)" },
Elly Jones03cd6d72012-06-11 13:04:28 -0400161 { "verified boot", "/bin/cat /var/log/debug_vboot_noisy.log" },
162 { "vpd_2.0", "/bin/cat /var/log/vpd_2.0.txt" },
Samuel Tan107b6c82014-07-10 15:33:44 -0700163 { "wifi_status", "/usr/bin/network_diag --wifi-internal --no-log" },
Sonny Raoab5f9952013-07-17 14:13:53 -0700164 { "zram compressed data size",
165 "/bin/cat /sys/block/zram0/compr_data_size 2> /dev/null" },
166 { "zram original data size",
167 "/bin/cat /sys/block/zram0/orig_data_size 2> /dev/null" },
168 { "zram total memory used",
169 "/bin/cat /sys/block/zram0/mem_used_total 2> /dev/null" },
170 { "zram total reads",
171 "/bin/cat /sys/block/zram0/num_reads 2> /dev/null" },
172 { "zram total writes",
173 "/bin/cat /sys/block/zram0/num_writes 2> /dev/null" },
Gaurav Shah6e8fd892012-10-01 11:51:08 -0700174
Elly Jones03cd6d72012-06-11 13:04:28 -0400175 // Stuff pulled out of the original list. These need access to the running X
176 // session, which we'd rather not give to debugd, or return info specific to
177 // the current session (in the setsid(2) sense), which is not useful for
178 // debugd
179 // { "env", "set" },
180 // { "setxkbmap", "/usr/bin/setxkbmap -print -query" },
181 // { "xrandr", "/usr/bin/xrandr --verbose" }
Elly Jones533c7c42012-08-10 15:07:05 -0400182 { NULL, NULL }
183};
184
185static const Log extra_logs[] = {
Ben Chan36e42282014-02-12 22:32:34 -0800186#if USE_CELLULAR
Elly Jones533c7c42012-08-10 15:07:05 -0400187 { "mm-status", "/usr/bin/modem status" },
Ben Chan36e42282014-02-12 22:32:34 -0800188#endif // USE_CELLULAR
Elly Jones533c7c42012-08-10 15:07:05 -0400189 { "network-devices", "/usr/bin/connectivity show devices" },
190 { "network-services", "/usr/bin/connectivity show services" },
191 { NULL, NULL }
192};
193
Gaurav Shahf6c8f2a2012-10-11 17:22:43 -0700194static const Log feedback_logs[] = {
Ben Chan36e42282014-02-12 22:32:34 -0800195#if USE_CELLULAR
Elly Jones533c7c42012-08-10 15:07:05 -0400196 { "mm-status", "/usr/bin/modem status-feedback" },
Ben Chan36e42282014-02-12 22:32:34 -0800197#endif // USE_CELLULAR
Elly Jones533c7c42012-08-10 15:07:05 -0400198 { "network-devices", "/usr/bin/connectivity show-feedback devices" },
199 { "network-services", "/usr/bin/connectivity show-feedback services" },
200 { NULL, NULL }
Elly Jones03cd6d72012-06-11 13:04:28 -0400201};
202
Gaurav Shahf6c8f2a2012-10-11 17:22:43 -0700203// List of log files that must directly be collected by Chrome. This is because
204// debugd is running under a VFS namespace and does not have access to later
205// cryptohome mounts.
206static const Log user_logs[] = {
Elly Fong-Jones6456ce52013-04-17 13:31:13 -0400207 {"chrome_user_log", "log/chrome"},
208 {"login-times", "login-times"},
209 {"logout-times", "logout-times"},
Gaurav Shahf6c8f2a2012-10-11 17:22:43 -0700210 { NULL, NULL}
211};
212
Elly Jones533c7c42012-08-10 15:07:05 -0400213bool GetNamedLogFrom(const string& name, const struct Log* logs,
214 string* result) {
215 for (size_t i = 0; logs[i].name; i++) {
216 if (name == logs[i].name) {
Elly Fong-Jonesd9a16cd2012-11-12 16:09:49 -0500217 *result = Run(logs[i]);
Elly Jones533c7c42012-08-10 15:07:05 -0400218 return true;
219 }
220 }
221 *result = "<invalid log name>";
222 return false;
Elly Jones03cd6d72012-06-11 13:04:28 -0400223}
224
Ben Chana0011d82014-05-13 00:19:29 -0700225string LogTool::GetLog(const string& name, DBus::Error* error) {
Elly Jones533c7c42012-08-10 15:07:05 -0400226 string result;
227 GetNamedLogFrom(name, common_logs, &result)
228 || GetNamedLogFrom(name, extra_logs, &result)
229 || GetNamedLogFrom(name, feedback_logs, &result);
230 return result;
231}
232
233void GetLogsFrom(const struct Log* logs, LogTool::LogMap* map) {
234 for (size_t i = 0; logs[i].name; i++)
Elly Fong-Jonesd9a16cd2012-11-12 16:09:49 -0500235 (*map)[logs[i].name] = Run(logs[i]);
Elly Jones533c7c42012-08-10 15:07:05 -0400236}
237
Ben Chana0011d82014-05-13 00:19:29 -0700238LogTool::LogMap LogTool::GetAllLogs(DBus::Error* error) {
Elly Jones533c7c42012-08-10 15:07:05 -0400239 LogMap result;
240 GetLogsFrom(common_logs, &result);
241 GetLogsFrom(extra_logs, &result);
242 return result;
243}
244
Ben Chana0011d82014-05-13 00:19:29 -0700245LogTool::LogMap LogTool::GetFeedbackLogs(DBus::Error* error) {
Elly Jones533c7c42012-08-10 15:07:05 -0400246 LogMap result;
247 GetLogsFrom(common_logs, &result);
248 GetLogsFrom(feedback_logs, &result);
Darin Petkovce9b3a12013-01-10 16:38:54 +0100249 AnonymizeLogMap(&result);
Elly Jones03cd6d72012-06-11 13:04:28 -0400250 return result;
251}
252
Ben Chana0011d82014-05-13 00:19:29 -0700253LogTool::LogMap LogTool::GetUserLogFiles(DBus::Error* error) {
Gaurav Shahf6c8f2a2012-10-11 17:22:43 -0700254 LogMap result;
255 for (size_t i = 0; user_logs[i].name; ++i)
256 result[user_logs[i].name] = user_logs[i].command;
257 return result;
258}
259
Darin Petkovce9b3a12013-01-10 16:38:54 +0100260void LogTool::AnonymizeLogMap(LogMap* log_map) {
261 AnonymizerTool anonymizer;
262 for (LogMap::iterator it = log_map->begin();
263 it != log_map->end(); ++it) {
264 it->second = anonymizer.Anonymize(it->second);
265 }
266}
267
Ben Chana0011d82014-05-13 00:19:29 -0700268} // namespace debugd