blob: 335ee60ce9b700f7acfa69d4f41e544339ec1330 [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 Chan8e9f6d02017-09-26 23:04:21 -07007#include <memory>
Ben Chana0011d82014-05-13 00:19:29 -07008#include <vector>
9
Ben Chanab93abf2017-01-24 13:32:51 -080010#include <base/base64.h>
Ben Chancd8fda42014-09-05 08:21:06 -070011#include <base/files/file_util.h>
Ahmed Fakhry21140cf2016-03-04 17:15:19 -080012#include <base/json/json_writer.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>
Ahmed Fakhry21140cf2016-03-04 17:15:19 -080016#include <base/values.h>
Elly Jones03cd6d72012-06-11 13:04:28 -040017
Rebecca Silbersteine78af402014-10-02 10:55:04 -070018#include <chromeos/dbus/service_constants.h>
Eric Carusocc7106c2017-04-27 14:22:42 -070019#include <shill/dbus-proxies.h>
Rebecca Silbersteine78af402014-10-02 10:55:04 -070020
Ben Chanaf125862017-02-08 23:11:18 -080021#include "debugd/src/constants.h"
Alex Vakulenko262be3f2014-07-30 15:25:50 -070022#include "debugd/src/process_with_output.h"
Elly Jones03cd6d72012-06-11 13:04:28 -040023
24namespace debugd {
25
Elly Jones03cd6d72012-06-11 13:04:28 -040026using std::string;
Elly Jones03cd6d72012-06-11 13:04:28 -040027
Eric Caruso96d03d32017-04-25 18:01:17 -070028using Strings = std::vector<string>;
Elly Jones03cd6d72012-06-11 13:04:28 -040029
Ahmed Fakhry21140cf2016-03-04 17:15:19 -080030namespace {
31
Ben Chanaf125862017-02-08 23:11:18 -080032const char kRoot[] = "root";
33const char kShell[] = "/bin/sh";
Ahmed Fakhry21140cf2016-03-04 17:15:19 -080034
35// Minimum time in seconds needed to allow shill to test active connections.
36const int kConnectionTesterTimeoutSeconds = 5;
Ben Chanf6cd93a2012-10-14 19:37:00 -070037
Elly Fong-Jonesd9a16cd2012-11-12 16:09:49 -050038struct Log {
39 const char *name;
40 const char *command;
41 const char *user;
42 const char *group;
Ricky Zhou4c473ca2016-06-21 17:46:58 -070043 const char *size_cap; // passed as arg to 'tail'
Elly Fong-Jonesd9a16cd2012-11-12 16:09:49 -050044};
45
Eric Carusoa879fd92017-10-11 12:57:10 -070046#define CMD_KERNEL_MODULE_PARAMS(module_name) \
Luigi Semenzato7e2c08f2018-06-26 14:58:49 -070047 "cd /sys/module/" #module_name "/parameters 2>/dev/null && grep -sH ^ *"
Eric Carusoa879fd92017-10-11 12:57:10 -070048
Ben Chancf7d6412017-08-10 22:30:09 -070049const Log kCommandLogs[] = {
Mike Frysingerc3e835a2017-01-06 04:09:34 -050050 { "CLIENT_ID", "/usr/bin/metrics_client -i"},
Elly Jones03cd6d72012-06-11 13:04:28 -040051 { "LOGDATE", "/bin/date" },
Luigi Semenzato7e2c08f2018-06-26 14:58:49 -070052 { "atrus_logs", "cat /var/log/atrus.log 2>/dev/null" },
53 { "authpolicy", "cat /var/log/authpolicy.log" },
54 { "bios_info", "cat /var/log/bios_info.txt" },
Vadim Bendebury64aeeed2013-09-16 13:16:49 -070055 { "bios_log",
Luigi Semenzato7e2c08f2018-06-26 14:58:49 -070056 "cat /sys/firmware/log "
57 "/proc/device-tree/chosen/ap-console-buffer 2>/dev/null" },
58 { "bios_times", "cat /var/log/bios_times.txt" },
Elly Jones03cd6d72012-06-11 13:04:28 -040059 { "board-specific",
Thiemo Nagela269ad22014-11-27 17:13:01 +010060 "/usr/share/userfeedback/scripts/get_board_specific_info" },
Luigi Semenzato7e2c08f2018-06-26 14:58:49 -070061 { "buddyinfo", "cat /proc/buddyinfo" },
Daisuke Nojiri3d832ee2017-02-17 14:21:28 -080062 { "cbi_info", "/usr/share/userfeedback/scripts/cbi_info", kRoot, },
Olof Johanssone5d0fd32016-01-29 14:40:34 -080063 { "cheets_log", "/usr/bin/collect-cheets-logs 2>&1" },
Luigi Semenzato7e2c08f2018-06-26 14:58:49 -070064 { "clobber.log", "cat /var/log/clobber.log 2>/dev/null" },
65 { "clobber-state.log", "cat /var/log/clobber-state.log 2>/dev/null" },
66 { "chrome_system_log", "cat /var/log/chrome/chrome" },
Mike Frysinger32cdf3e2017-08-14 18:17:06 -040067 // There might be more than one record, so grab them all.
68 // Plus, for <linux-3.19, it's named "console-ramoops", but for newer
69 // versions, it's named "console-ramoops-#".
Luigi Semenzato7e2c08f2018-06-26 14:58:49 -070070 { "console-ramoops", "cat /sys/fs/pstore/console-ramoops* 2>/dev/null" },
Elly Jones03cd6d72012-06-11 13:04:28 -040071 { "cpu", "/usr/bin/uname -p" },
Luigi Semenzato7e2c08f2018-06-26 14:58:49 -070072 { "cpuinfo", "cat /proc/cpuinfo" },
73 { "cr50_version", "cat /var/cache/cr50-version" },
Eric Caruso57333f12015-09-08 12:50:32 -070074 { "cros_ec",
Luigi Semenzato7e2c08f2018-06-26 14:58:49 -070075 "cat /var/log/cros_ec.previous /var/log/cros_ec.log 2>/dev/null" },
Nicolas Boichat083795f2016-08-16 11:16:49 +020076 { "cros_ec_panicinfo",
Luigi Semenzato7e2c08f2018-06-26 14:58:49 -070077 "cat /sys/kernel/debug/cros_ec/panicinfo 2>/dev/null",
Nicolas Boichatd51092b2016-09-01 10:36:46 +080078 SandboxedProcess::kDefaultUser,
79 kDebugfsGroup
80 },
Shawn Nematbakhsh60813732017-07-13 10:46:23 -070081 { "cros_ec_pdinfo",
Luigi Semenzato7e2c08f2018-06-26 14:58:49 -070082 "cat /sys/kernel/debug/cros_ec/pdinfo 2>/dev/null",
Shawn Nematbakhsh60813732017-07-13 10:46:23 -070083 SandboxedProcess::kDefaultUser,
84 kDebugfsGroup
85 },
Vincent Palatine3588042018-04-04 17:02:38 +020086 { "cros_fp",
Luigi Semenzato7e2c08f2018-06-26 14:58:49 -070087 "cat /var/log/cros_fp.previous /var/log/cros_fp.log 2>/dev/null" },
Elly Jones03cd6d72012-06-11 13:04:28 -040088 { "dmesg", "/bin/dmesg" },
Luigi Semenzato7e2c08f2018-06-26 14:58:49 -070089 { "ec_info", "cat /var/log/ec_info.txt" },
Miguel Casas8d4e54f2018-03-29 09:42:52 -040090 // The sed command replaces the EDID serial number (4 bytes at position 12)
91 // with zeroes. See https://en.wikipedia.org/wiki/EDID#EDID_1.4_data_format.
92 { "edid-decode",
93 "for f in /sys/class/drm/card0-*/edid; do"
94 "echo \"----------- ${f}\"; "
95 "sed -E 's/.{4}/\x00\x00\x00\x00/4' \"${f}\" | edid-decode;"
96 "done"
97 },
Luigi Semenzato7e2c08f2018-06-26 14:58:49 -070098 { "eventlog", "cat /var/log/eventlog.txt" },
Elly Fong-Jones215b5622013-03-20 14:32:18 -040099 {
100 "exynos_gem_objects",
Luigi Semenzato7e2c08f2018-06-26 14:58:49 -0700101 "cat /sys/kernel/debug/dri/0/exynos_gem_objects 2>/dev/null",
Elly Fong-Jones215b5622013-03-20 14:32:18 -0400102 SandboxedProcess::kDefaultUser,
103 kDebugfsGroup
104 },
Elly Jones03cd6d72012-06-11 13:04:28 -0400105 { "font_info", "/usr/share/userfeedback/scripts/font_info" },
Daisuke Nojiridebede0e2017-02-17 14:21:28 -0800106 { "sensor_info", "/usr/share/userfeedback/scripts/sensor_info" },
Elly Jones03cd6d72012-06-11 13:04:28 -0400107 { "hardware_class", "/usr/bin/crossystem hwid" },
108 { "hostname", "/bin/hostname" },
109 { "hw_platform", "/usr/bin/uname -i" },
Elly Fong-Jones215b5622013-03-20 14:32:18 -0400110 {
111 "i915_gem_gtt",
Luigi Semenzato7e2c08f2018-06-26 14:58:49 -0700112 "cat /sys/kernel/debug/dri/0/i915_gem_gtt 2>/dev/null",
Elly Fong-Jones215b5622013-03-20 14:32:18 -0400113 SandboxedProcess::kDefaultUser,
114 kDebugfsGroup
115 },
116 {
117 "i915_gem_objects",
Luigi Semenzato7e2c08f2018-06-26 14:58:49 -0700118 "cat /sys/kernel/debug/dri/0/i915_gem_objects 2>/dev/null",
Elly Fong-Jones215b5622013-03-20 14:32:18 -0400119 SandboxedProcess::kDefaultUser,
120 kDebugfsGroup
121 },
122 {
123 "i915_error_state",
Luigi Semenzato7e2c08f2018-06-26 14:58:49 -0700124 "/usr/bin/xz -c /sys/kernel/debug/dri/0/i915_error_state 2>/dev/null",
Elly Fong-Jones215b5622013-03-20 14:32:18 -0400125 SandboxedProcess::kDefaultUser,
126 kDebugfsGroup,
127 },
Daniel Erat982ab4b2014-04-09 07:32:38 -0700128 { "ifconfig", "/bin/ifconfig -a" },
Luigi Semenzato7e2c08f2018-06-26 14:58:49 -0700129 { "input_devices", "cat /proc/bus/input/devices" },
Eric Carusob1820c02017-08-24 15:39:56 -0700130 // Information about the wiphy device, such as current channel.
131 { "iw_dev", "/usr/sbin/iw dev" },
132 // Hardware capabilities of the wiphy device.
133 { "iw_list", "/usr/sbin/iw list" },
Eric Carusoa879fd92017-10-11 12:57:10 -0700134#if USE_IWLWIFI_DUMP
135 { "iwlmvm_module_params", CMD_KERNEL_MODULE_PARAMS(iwlmvm) },
136 { "iwlwifi_module_params", CMD_KERNEL_MODULE_PARAMS(iwlwifi) },
137#endif // USE_IWLWIFI_DUMP
Luigi Semenzato7e2c08f2018-06-26 14:58:49 -0700138 { "kernel-crashes", "cat /var/spool/crash/kernel.*.kcrash 2>/dev/null" },
139 { "logcat",
140 "/usr/sbin/android-sh -c '/system/bin/logcat -d'",
Kevin Cernekee143e2af2018-03-20 13:28:20 -0700141 kRoot,
142 kRoot,
143 },
Elly Jones03cd6d72012-06-11 13:04:28 -0400144 { "lsmod", "lsmod" },
145 { "lspci", "/usr/sbin/lspci" },
Simon Que41c88b52017-06-19 14:05:07 -0400146 { "lsusb", "lsusb && lsusb -t" },
Luigi Semenzato7e2c08f2018-06-26 14:58:49 -0700147 { "mali_memory", "cat /sys/class/misc/mali0/device/memory 2>/dev/null" },
Luigi Semenzato7f00dfb2018-06-26 11:34:02 -0700148 { "memd.parameters", "cat /var/log/memd/memd.parameters 2>/dev/null" },
149 { "memd clips", "cat /var/log/memd/memd.clip* 2>/dev/null" },
Elly Jones03cd6d72012-06-11 13:04:28 -0400150 { "meminfo", "cat /proc/meminfo" },
Mike Frysinger8fd2eee2017-11-03 14:35:26 -0400151 {
152 "memory_spd_info",
153 // mosys may use 'i2c-dev', which may not be loaded yet.
154 "modprobe i2c-dev 2>/dev/null && "
155 "mosys -l memory spd print all 2>/dev/null",
156 kRoot,
157 kDebugfsGroup,
158 },
Simon Quecb63b9c2017-06-19 14:53:31 -0400159 // The sed command finds the EDID blob (starting the line after "value:") and
160 // replaces the serial number with all zeroes.
161 //
162 // The EDID is printed as a hex dump over several lines, each line containing
163 // the contents of 16 bytes. The first 16 bytes are broken down as follows:
164 // uint64_t fixed_pattern; // Always 00 FF FF FF FF FF FF 00.
165 // uint16_t manufacturer_id; // Manufacturer ID, encoded as PNP IDs.
166 // uint16_t product_code; // Manufacturer product code, little-endian.
167 // uint32_t serial_number; // Serial number, little-endian.
168 // Source: https://en.wikipedia.org/wiki/EDID#EDID_1.3_data_format
169 //
170 // The subsequent substitution command looks for the fixed pattern followed by
171 // two 32-bit fields (manufacturer + product, serial number). It replaces the
172 // latter field with 8 bytes of zeroes.
173 //
174 // TODO(crbug.com/731133): Remove the sed command once modetest itself can
175 // remove serial numbers.
176 {
177 "modetest",
178 "(modetest; modetest -M evdi; modetest -M udl) | "
179 "sed -E '/EDID/ {:a;n;/value:/!ba;n;"
180 "s/(00f{12}00)([0-9a-f]{8})([0-9a-f]{8})/\\1\\200000000/}'",
181 kRoot,
182 kRoot,
183 },
Luigi Semenzato7e2c08f2018-06-26 14:58:49 -0700184 { "mount-encrypted", "cat /var/log/mount-encrypted.log" },
185 { "mountinfo", "cat /proc/1/mountinfo" },
Nicolas Boichat0230b0b2017-08-17 11:20:19 +0800186 { "netlog", "/usr/share/userfeedback/scripts/getmsgs /var/log/net.log" },
Kevin Cernekee143e2af2018-03-20 13:28:20 -0700187 // --processes requires root.
188 { "netstat", "/sbin/ss --all --query inet --numeric --processes",
189 kRoot,
190 kRoot,
191 },
henryhsufa6daa12014-09-24 13:26:30 +0800192 {
193 "nvmap_iovmm",
Luigi Semenzato7e2c08f2018-06-26 14:58:49 -0700194 "cat /sys/kernel/debug/nvmap/iovmm/allocations 2>/dev/null",
henryhsufa6daa12014-09-24 13:26:30 +0800195 SandboxedProcess::kDefaultUser,
196 kDebugfsGroup,
197 },
Todd Brocha0c13762018-05-03 11:31:25 -0700198 { "oemdata", "/usr/share/cros/oemdata.sh", kRoot, kRoot, },
Luigi Semenzato7e2c08f2018-06-26 14:58:49 -0700199 { "pagetypeinfo", "cat /proc/pagetypeinfo" },
Mike Frysinger8fd2eee2017-11-03 14:35:26 -0400200 {
201 "platform_info",
202 // mosys may use 'i2c-dev', which may not be loaded yet.
203 "modprobe i2c-dev 2>/dev/null && "
204 "for param in "
205 "vendor "
206 "name "
207 "version "
208 "family "
209 "model "
210 "sku "
211 "customization "
212 "; do "
213 "mosys -l platform \"${param}\" 2>/dev/null; "
214 "done",
215 kRoot,
216 kDebugfsGroup,
217 },
Daniel Erat9b58b6d2013-04-30 14:58:56 -0700218 { "power_supply_info", "/usr/bin/power_supply_info" },
Daniel Eratd8b84992017-03-13 17:30:00 -0600219 { "power_supply_sysfs", "/usr/bin/print_sysfs_power_supply_data" },
Luigi Semenzato7e2c08f2018-06-26 14:58:49 -0700220 { "powerd.LATEST", "cat /var/log/power_manager/powerd.LATEST" },
221 { "powerd.PREVIOUS", "cat /var/log/power_manager/powerd.PREVIOUS" },
222 { "powerd.out", "cat /var/log/powerd.out" },
223 { "powerwash_count", "cat /var/log/powerwash_count 2>/dev/null" },
Mattias Nissler887dce22017-07-03 14:44:35 +0200224 // Changed from 'ps ux' to 'ps aux' since we're running as debugd,
225 // not chronos.
Elly Jones03cd6d72012-06-11 13:04:28 -0400226 { "ps", "/bin/ps aux" },
yusukes34171ba2017-04-27 15:46:01 -0700227 // /proc/slabinfo is owned by root and has 0400 permission.
Luigi Semenzato7e2c08f2018-06-26 14:58:49 -0700228 { "slabinfo", "cat /proc/slabinfo", kRoot, kRoot, },
229 { "storage_info", "cat /var/log/storage_info.txt" },
Alexis Saverybbb85132018-05-18 17:41:10 -0700230 { "swap_info",
231 "/usr/share/cros/init/swap.sh status 2>/dev/null",
232 SandboxedProcess::kDefaultUser,
233 kDebugfsGroup
234 },
Nicolas Boichat0230b0b2017-08-17 11:20:19 +0800235 { "syslog", "/usr/share/userfeedback/scripts/getmsgs /var/log/messages" },
Brandon Mayere24c7a22017-08-04 13:58:48 -0400236 { "system_log_stats", "echo 'BLOCK_SIZE=1024'; "
237 "find /var/log/ -type f -exec du --block-size=1024 {} + | sort -n -r",
238 kRoot, kRoot},
Kuo-Hsin Yang379846b2018-06-04 11:16:55 +0800239 { "threads", "/bin/ps -T axo pid,ppid,spid,pcpu,ni,stat,time,comm" },
Luigi Semenzato7e2c08f2018-06-26 14:58:49 -0700240 { "tlsdate", "cat /var/log/tlsdate.log" },
Hsu-Cheng Tsaie8c31d52017-03-31 12:34:55 +0800241 { "top thread", "/usr/bin/top -Hb -n 1 | head -n 40"},
242 { "top memory", "/usr/bin/top -o \"+%MEM\" -bn 1 | head -n 57"},
Andrew de los Reyesc060c342013-04-10 13:46:30 -0700243 { "touch_fw_version", "grep -E"
Charlie Mooneybb08f982016-02-04 15:35:56 -0800244 " -e 'synaptics: Touchpad model'"
245 " -e 'chromeos-[a-z]*-touch-[a-z]*-update'"
Andrew de los Reyesc060c342013-04-10 13:46:30 -0700246 " /var/log/messages | tail -n 20" },
Mattias Nissler483d76f2017-08-23 16:53:36 +0200247 {
248 "tpm-firmware-updater",
249 "/usr/share/userfeedback/scripts/getmsgs /var/log/tpm-firmware-updater.log"
250 },
Mattias Nissler887dce22017-07-03 14:44:35 +0200251 // TODO(jorgelo,mnissler): Don't run this as root.
252 // On TPM 1.2 devices this will likely require adding a new user to the 'tss'
253 // group.
254 // On TPM 2.0 devices 'get_version_info' uses D-Bus and therefore can run as
255 // any user.
256 { "tpm_version", "/usr/sbin/tpm-manager get_version_info", kRoot, kRoot },
Charlie Mooney69f56702017-05-02 14:55:41 -0700257 { "atmel_ts_refs", "/opt/google/touch/scripts/atmel_tools.sh ts r",
258 kRoot, kRoot},
259 { "atmel_tp_refs", "/opt/google/touch/scripts/atmel_tools.sh tp r",
260 kRoot, kRoot},
261 { "atmel_ts_deltas", "/opt/google/touch/scripts/atmel_tools.sh ts d",
262 kRoot, kRoot},
263 { "atmel_tp_deltas", "/opt/google/touch/scripts/atmel_tools.sh tp d",
264 kRoot, kRoot},
Gwendal Grignou427d94e2016-10-25 11:34:51 -0700265 {
266 "trim",
267 "cat /var/lib/trim/stateful_trim_state /var/lib/trim/stateful_trim_data"
268 },
Elly Jones03cd6d72012-06-11 13:04:28 -0400269 { "ui_log", "/usr/share/userfeedback/scripts/get_log /var/log/ui/ui.LATEST" },
270 { "uname", "/bin/uname -a" },
271 { "update_engine.log", "cat $(ls -1tr /var/log/update_engine | tail -5 | sed"
Thiemo Nagela269ad22014-11-27 17:13:01 +0100272 " s.^./var/log/update_engine/.)" },
Dariusz Marcinkiewiczc4126882017-10-13 16:07:36 +0200273 { "uptime", "/usr/bin/cut -d' ' -f1 /proc/uptime" },
Luigi Semenzato7e2c08f2018-06-26 14:58:49 -0700274 { "verified boot", "cat /var/log/debug_vboot_noisy.log" },
275 { "vmlog.1.LATEST", "cat /var/log/vmlog/vmlog.1.LATEST" },
276 { "vmlog.1.PREVIOUS", "cat /var/log/vmlog/vmlog.1.PREVIOUS" },
277 { "vmlog.LATEST", "cat /var/log/vmlog/vmlog.LATEST" },
278 { "vmlog.PREVIOUS", "cat /var/log/vmlog/vmlog.PREVIOUS" },
279 { "vmstat", "cat /proc/vmstat" },
280 { "vpd_2.0", "cat /var/log/vpd_2.0.txt" },
Samuel Tan107b6c82014-07-10 15:33:44 -0700281 { "wifi_status", "/usr/bin/network_diag --wifi-internal --no-log" },
Sonny Raoab5f9952013-07-17 14:13:53 -0700282 { "zram compressed data size",
Luigi Semenzato7e2c08f2018-06-26 14:58:49 -0700283 "cat /sys/block/zram0/compr_data_size 2>/dev/null" },
Sonny Raoab5f9952013-07-17 14:13:53 -0700284 { "zram original data size",
Luigi Semenzato7e2c08f2018-06-26 14:58:49 -0700285 "cat /sys/block/zram0/orig_data_size 2>/dev/null" },
Sonny Raoab5f9952013-07-17 14:13:53 -0700286 { "zram total memory used",
Luigi Semenzato7e2c08f2018-06-26 14:58:49 -0700287 "cat /sys/block/zram0/mem_used_total 2>/dev/null" },
Sonny Raoab5f9952013-07-17 14:13:53 -0700288 { "zram total reads",
Luigi Semenzato7e2c08f2018-06-26 14:58:49 -0700289 "cat /sys/block/zram0/num_reads 2>/dev/null" },
Sonny Raoab5f9952013-07-17 14:13:53 -0700290 { "zram total writes",
Luigi Semenzato7e2c08f2018-06-26 14:58:49 -0700291 "cat /sys/block/zram0/num_writes 2>/dev/null" },
292 { "zram new stats names",
293 "echo orig_size compr_size used_total limit "
Luigi Semenzato4164de42017-07-06 10:42:54 -0700294 "used_max zero_pages migrated" },
Luigi Semenzato7e2c08f2018-06-26 14:58:49 -0700295 { "zram new stats values", "cat /sys/block/zram0/mm_stat 2>/dev/null" },
296 { "cros_tp version", "cat /sys/class/chromeos/cros_tp/version" },
Wei-Ning Huang230b7d82017-07-14 16:19:13 +0800297 { "cros_tp console", "/usr/sbin/ectool --name=cros_tp console",
298 kRoot, kRoot },
Wei-Ning Huang23ffdcf2017-08-04 11:30:39 +0800299 { "cros_tp frame", "/usr/sbin/ectool --name=cros_tp tpframeget",
300 kRoot, kRoot },
Gaurav Shah6e8fd892012-10-01 11:51:08 -0700301
Elly Jones03cd6d72012-06-11 13:04:28 -0400302 // Stuff pulled out of the original list. These need access to the running X
303 // session, which we'd rather not give to debugd, or return info specific to
304 // the current session (in the setsid(2) sense), which is not useful for
305 // debugd
306 // { "env", "set" },
307 // { "setxkbmap", "/usr/bin/setxkbmap -print -query" },
308 // { "xrandr", "/usr/bin/xrandr --verbose" }
Ben Chan64d19b22017-02-06 14:03:47 -0800309 { nullptr, nullptr }
Elly Jones533c7c42012-08-10 15:07:05 -0400310};
311
Kevin Cernekee143e2af2018-03-20 13:28:20 -0700312// netstat and logcat should appear in chrome://system but not in feedback
313// reports. Open sockets may have privacy implications, and logcat is
314// already incorporated via arc-bugreport.
315const std::vector<string> kCommandLogsExclude = {"netstat", "logcat"};
316
Ben Chancf7d6412017-08-10 22:30:09 -0700317const Log kExtraLogs[] = {
Ben Chan36e42282014-02-12 22:32:34 -0800318#if USE_CELLULAR
Elly Jones533c7c42012-08-10 15:07:05 -0400319 { "mm-status", "/usr/bin/modem status" },
Ben Chan36e42282014-02-12 22:32:34 -0800320#endif // USE_CELLULAR
Elly Jones533c7c42012-08-10 15:07:05 -0400321 { "network-devices", "/usr/bin/connectivity show devices" },
322 { "network-services", "/usr/bin/connectivity show services" },
Ben Chan64d19b22017-02-06 14:03:47 -0800323 { nullptr, nullptr }
Elly Jones533c7c42012-08-10 15:07:05 -0400324};
325
Ben Chancf7d6412017-08-10 22:30:09 -0700326const Log kFeedbackLogs[] = {
Ben Chan36e42282014-02-12 22:32:34 -0800327#if USE_CELLULAR
Elly Jones533c7c42012-08-10 15:07:05 -0400328 { "mm-status", "/usr/bin/modem status-feedback" },
Ben Chan36e42282014-02-12 22:32:34 -0800329#endif // USE_CELLULAR
Elly Jones533c7c42012-08-10 15:07:05 -0400330 { "network-devices", "/usr/bin/connectivity show-feedback devices" },
331 { "network-services", "/usr/bin/connectivity show-feedback services" },
Ben Chan64d19b22017-02-06 14:03:47 -0800332 { nullptr, nullptr }
Elly Jones03cd6d72012-06-11 13:04:28 -0400333};
334
Ahmed Fakhry1498b4e2016-03-30 12:42:20 -0700335// List of log files needed to be part of the feedback report that are huge and
336// must be sent back to the client via the file descriptor using
337// LogTool::GetBigFeedbackLogs().
Ben Chancf7d6412017-08-10 22:30:09 -0700338const Log kBigFeedbackLogs[] = {
Eric Carusoe3166f22016-06-10 15:36:02 -0700339 { "arc-bugreport",
Luigi Semenzato7e2c08f2018-06-26 14:58:49 -0700340 "cat /run/arc/bugreport/pipe 2>/dev/null",
Eric Carusoe3166f22016-06-10 15:36:02 -0700341 // ARC bugreport permissions are weird. Since we're just running cat, this
342 // shouldn't cause any issues.
343 kRoot,
Ricky Zhou4c473ca2016-06-21 17:46:58 -0700344 kRoot,
345 "10M",
Eric Carusoe3166f22016-06-10 15:36:02 -0700346 },
Ben Chan64d19b22017-02-06 14:03:47 -0800347 { nullptr, nullptr }
Ahmed Fakhry1498b4e2016-03-30 12:42:20 -0700348};
349
Gaurav Shahf6c8f2a2012-10-11 17:22:43 -0700350// List of log files that must directly be collected by Chrome. This is because
351// debugd is running under a VFS namespace and does not have access to later
352// cryptohome mounts.
Ben Chancf7d6412017-08-10 22:30:09 -0700353const Log kUserLogs[] = {
Elly Fong-Jones6456ce52013-04-17 13:31:13 -0400354 {"chrome_user_log", "log/chrome"},
355 {"login-times", "login-times"},
356 {"logout-times", "logout-times"},
Ben Chan64d19b22017-02-06 14:03:47 -0800357 { nullptr, nullptr}
Gaurav Shahf6c8f2a2012-10-11 17:22:43 -0700358};
359
Ahmed Fakhry21140cf2016-03-04 17:15:19 -0800360// Returns |value| if |value| is a valid UTF-8 string or a base64-encoded
361// string of |value| otherwise.
362string EnsureUTF8String(const string& value) {
363 if (base::IsStringUTF8(value))
364 return value;
365
Eric Caruso96d03d32017-04-25 18:01:17 -0700366 string encoded_value;
Ben Chanab93abf2017-01-24 13:32:51 -0800367 base::Base64Encode(value, &encoded_value);
368 return "<base64>: " + encoded_value;
Ahmed Fakhry21140cf2016-03-04 17:15:19 -0800369}
370
371// TODO(ellyjones): sandbox. crosbug.com/35122
372string Run(const Log& log) {
373 string output;
374 ProcessWithOutput p;
Eric Caruso96d03d32017-04-25 18:01:17 -0700375 string tailed_cmdline = string(log.command) + " | tail -c " +
Ahmed Fakhrye4a0b502016-09-19 18:18:49 -0700376 (log.size_cap ? log.size_cap : "512K");
Ahmed Fakhry21140cf2016-03-04 17:15:19 -0800377 if (log.user && log.group)
378 p.SandboxAs(log.user, log.group);
379 if (!p.Init())
380 return "<not available>";
381 p.AddArg(kShell);
382 p.AddStringOption("-c", tailed_cmdline);
383 if (p.Run())
384 return "<not available>";
385 p.GetOutput(&output);
386 if (!output.size())
387 return "<empty>";
388 return EnsureUTF8String(output);
389}
390
391// Fills |dictionary| with the anonymized contents of the logs in |logs|.
392void GetLogsInDictionary(const struct Log* logs,
393 AnonymizerTool* anonymizer,
394 base::DictionaryValue* dictionary) {
395 for (size_t i = 0; logs[i].name; ++i) {
396 dictionary->SetStringWithoutPathExpansion(
397 logs[i].name, anonymizer->Anonymize(Run(logs[i])));
398 }
399}
400
401// Serializes the |dictionary| into the file with the given |fd| in a JSON
402// format.
403void SerializeLogsAsJSON(const base::DictionaryValue& dictionary,
Eric Caruso0b241882018-04-04 13:43:46 -0700404 const base::ScopedFD& fd) {
Eric Caruso96d03d32017-04-25 18:01:17 -0700405 string logs_json;
Ahmed Fakhry21140cf2016-03-04 17:15:19 -0800406 base::JSONWriter::WriteWithOptions(dictionary,
407 base::JSONWriter::OPTIONS_PRETTY_PRINT,
408 &logs_json);
Eric Caruso0b241882018-04-04 13:43:46 -0700409 base::WriteFileDescriptor(fd.get(), logs_json.c_str(), logs_json.size());
Ahmed Fakhry21140cf2016-03-04 17:15:19 -0800410}
411
Elly Jones533c7c42012-08-10 15:07:05 -0400412bool GetNamedLogFrom(const string& name, const struct Log* logs,
413 string* result) {
414 for (size_t i = 0; logs[i].name; i++) {
415 if (name == logs[i].name) {
Elly Fong-Jonesd9a16cd2012-11-12 16:09:49 -0500416 *result = Run(logs[i]);
Elly Jones533c7c42012-08-10 15:07:05 -0400417 return true;
418 }
419 }
420 *result = "<invalid log name>";
421 return false;
Elly Jones03cd6d72012-06-11 13:04:28 -0400422}
423
Ahmed Fakhry21140cf2016-03-04 17:15:19 -0800424void GetLogsFrom(const struct Log* logs, LogTool::LogMap* map) {
425 for (size_t i = 0; logs[i].name; i++)
426 (*map)[logs[i].name] = Run(logs[i]);
427}
428
429} // namespace
430
Eric Carusof9091f82017-04-28 14:18:59 -0700431void LogTool::CreateConnectivityReport() {
Rebecca Silbersteine78af402014-10-02 10:55:04 -0700432 // Perform ConnectivityTrial to report connection state in feedback log.
Ben Chan8e9f6d02017-09-26 23:04:21 -0700433 auto shill = std::make_unique<org::chromium::flimflam::ManagerProxy>(bus_);
Rebecca Silbersteine78af402014-10-02 10:55:04 -0700434 // Give the connection trial time to test the connection and log the results
435 // before collecting the logs for feedback.
436 // TODO(silberst): Replace the simple approach of a single timeout with a more
437 // coordinated effort.
Eric Carusocc7106c2017-04-27 14:22:42 -0700438 if (shill && shill->CreateConnectivityReport(nullptr))
439 sleep(kConnectionTesterTimeoutSeconds);
Rebecca Silbersteine78af402014-10-02 10:55:04 -0700440}
441
Eric Carusoc93a15c2017-04-24 16:15:12 -0700442string LogTool::GetLog(const string& name) {
Elly Jones533c7c42012-08-10 15:07:05 -0400443 string result;
Ben Chancf7d6412017-08-10 22:30:09 -0700444 GetNamedLogFrom(name, kCommandLogs, &result)
445 || GetNamedLogFrom(name, kExtraLogs, &result)
446 || GetNamedLogFrom(name, kFeedbackLogs, &result);
Elly Jones533c7c42012-08-10 15:07:05 -0400447 return result;
448}
449
Eric Carusof9091f82017-04-28 14:18:59 -0700450LogTool::LogMap LogTool::GetAllLogs() {
451 CreateConnectivityReport();
Elly Jones533c7c42012-08-10 15:07:05 -0400452 LogMap result;
Ben Chancf7d6412017-08-10 22:30:09 -0700453 GetLogsFrom(kCommandLogs, &result);
454 GetLogsFrom(kExtraLogs, &result);
Elly Jones533c7c42012-08-10 15:07:05 -0400455 return result;
456}
457
Brian Norrisca4fc042018-04-03 00:24:26 -0700458LogTool::LogMap LogTool::GetAllDebugLogs() {
459 CreateConnectivityReport();
460 LogMap result;
461 GetLogsFrom(kCommandLogs, &result);
462 GetLogsFrom(kExtraLogs, &result);
463 GetLogsFrom(kBigFeedbackLogs, &result);
464 return result;
465}
466
Eric Carusof9091f82017-04-28 14:18:59 -0700467LogTool::LogMap LogTool::GetFeedbackLogs() {
468 CreateConnectivityReport();
Elly Jones533c7c42012-08-10 15:07:05 -0400469 LogMap result;
Ben Chancf7d6412017-08-10 22:30:09 -0700470 GetLogsFrom(kCommandLogs, &result);
Kevin Cernekee143e2af2018-03-20 13:28:20 -0700471 for (const auto& key : kCommandLogsExclude) {
472 result.erase(key);
473 }
Ben Chancf7d6412017-08-10 22:30:09 -0700474 GetLogsFrom(kFeedbackLogs, &result);
Darin Petkovce9b3a12013-01-10 16:38:54 +0100475 AnonymizeLogMap(&result);
Elly Jones03cd6d72012-06-11 13:04:28 -0400476 return result;
477}
478
Eric Caruso0b241882018-04-04 13:43:46 -0700479void LogTool::GetBigFeedbackLogs(const base::ScopedFD& fd) {
Eric Carusof9091f82017-04-28 14:18:59 -0700480 CreateConnectivityReport();
Ahmed Fakhry21140cf2016-03-04 17:15:19 -0800481 base::DictionaryValue dictionary;
Ben Chancf7d6412017-08-10 22:30:09 -0700482 GetLogsInDictionary(kCommandLogs, &anonymizer_, &dictionary);
Kevin Cernekee143e2af2018-03-20 13:28:20 -0700483 for (const auto& key : kCommandLogsExclude) {
484 dictionary.Remove(key, nullptr);
485 }
Ben Chancf7d6412017-08-10 22:30:09 -0700486 GetLogsInDictionary(kFeedbackLogs, &anonymizer_, &dictionary);
487 GetLogsInDictionary(kBigFeedbackLogs, &anonymizer_, &dictionary);
Ahmed Fakhry21140cf2016-03-04 17:15:19 -0800488 SerializeLogsAsJSON(dictionary, fd);
489}
490
Eric Carusoc93a15c2017-04-24 16:15:12 -0700491LogTool::LogMap LogTool::GetUserLogFiles() {
Gaurav Shahf6c8f2a2012-10-11 17:22:43 -0700492 LogMap result;
Ben Chancf7d6412017-08-10 22:30:09 -0700493 for (size_t i = 0; kUserLogs[i].name; ++i)
494 result[kUserLogs[i].name] = kUserLogs[i].command;
Gaurav Shahf6c8f2a2012-10-11 17:22:43 -0700495 return result;
496}
497
Darin Petkovce9b3a12013-01-10 16:38:54 +0100498void LogTool::AnonymizeLogMap(LogMap* log_map) {
Ben Chane2fa3572017-02-08 22:46:18 -0800499 for (auto& entry : *log_map)
500 entry.second = anonymizer_.Anonymize(entry.second);
Darin Petkovce9b3a12013-01-10 16:38:54 +0100501}
502
Ben Chana0011d82014-05-13 00:19:29 -0700503} // namespace debugd