OLD | NEW |
---|---|
(Empty) | |
1 #!/bin/bash | |
2 | |
3 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved. | |
4 # Use of this source code is governed by a BSD-style license that can be | |
5 # found in the LICENSE file. | |
6 | |
7 # Script to generate stackdumps from a machine or dmp files. | |
8 | |
9 # Load common constants. This should be the first executable line. | |
10 # The path to common.sh should be relative to your script's location. | |
11 | |
12 . "$(dirname $0)/common.sh" | |
13 . "$(dirname $0)/remote_access.sh" | |
14 | |
15 restart_in_chroot_if_needed $* | |
16 | |
17 MINIDUMP_DUMP=/usr/bin/minidump_dump | |
18 MINIDUMP_STACKWALK=/usr/bin/minidump_stackwalk | |
19 USING_REMOTE=0 | |
20 | |
21 get_default_board | |
22 | |
23 DEFINE_string board "${DEFAULT_BOARD}" \ | |
24 "The board for which you are building autotest" | |
25 DEFINE_string breakpad_root "" \ | |
26 "Path to root of breakpad symbols if pre-existing symbols should be used" | |
27 DEFINE_boolean clean ${FLAGS_FALSE} \ | |
28 "Remove crash reports from remote system after showing stacks" | |
29 | |
30 function usage() { | |
31 echo "usage: $(basename $0) [--remote=<IP>] [dump...]" | |
32 echo "Specify either a remote IP of a ChromeOS device to gather " | |
33 echo "all crash reports from, or list crash reports" | |
34 exit 1 | |
35 } | |
36 | |
37 # Clean up remote access and temp files. | |
38 function cleanup() { | |
39 [ ${USING_REMOTE} -eq 1 ] && cleanup_remote_access | |
40 rm -rf "${TMP}" | |
41 } | |
42 | |
43 # Echoes kind of crash (minidump or kcrash). | |
44 function get_kind() { | |
45 local kind="${1##*.}" | |
46 if [ "${kind}" = "dmp" ]; then | |
47 kind="minidump" | |
48 fi | |
49 echo ${kind} | |
50 } | |
51 | |
52 # Generate symbols for the given module list. | |
53 # Args: | |
54 # $1 - file with a "module" per line. A module is the full target's | |
55 # path to a DSO or executable that was loaded during a crash. | |
56 function generate_symbols() { | |
57 local modules_file="$1" | |
58 local modules="" | |
59 local any_missing=0 | |
60 local module_count=0 | |
61 for module in $(cat ${modules_file} | sort | uniq); do | |
petkov
2010/08/31 05:23:50
no need for cat:
sort ${modules_file} | uniq
| |
62 local text_file="/build/${FLAGS_board}/${module}" | |
63 local debug_file="/build/${FLAGS_board}/usr/lib/debug/${module}.debug" | |
64 if [ -f "${text_file}" ] && [ -f "${debug_file}" ]; then | |
65 modules="${modules} ${text_file}" | |
66 module_count=$((module_count + 1)) | |
67 else | |
68 if [ ${any_missing} -eq 0 ]; then | |
69 warn "Some modules are missing debug information:" | |
70 any_missing=1 | |
71 fi | |
72 warn "* ${text_file}" | |
73 fi | |
74 done | |
75 if [ ${module_count} -gt 0 ]; then | |
76 info "Generating breakpad symbols for ${module_count} modules" | |
77 ${SCRIPTS_DIR}/cros_generate_breakpad_symbols --board=${FLAGS_board} \ | |
78 ${modules} | |
79 fi | |
80 } | |
81 | |
82 function main() { | |
petkov
2010/08/31 05:23:50
this routine feels a bit long -- consider breaking
| |
83 FLAGS "$@" || usage | |
84 local basename=$(basename "$0") | |
85 TMP=$(mktemp -d /tmp/${basename}.XXXX) | |
86 trap cleanup EXIT INT TERM | |
87 if [ -n "${FLAGS_remote}" ]; then | |
88 remote_access_init | |
89 USING_REMOTE=1 | |
90 learn_board | |
91 local crashes="" | |
92 # File spec of all interesting crashes. /home/chronos... is | |
93 # listed separately from /mnt/stateful_partition/home/chronos/... | |
94 # because the former may be a mount point for the cryptohome. | |
95 # This allows us to get crashes from the currently logged in | |
96 # user as well as from non-logged in users at once. We remove | |
97 # duplicate crashes (in case cryptohome is not mounted) below. | |
98 local remote_crash_dirs=" \ | |
99 /var/spool/crash \ | |
100 /home/chronos/user/crash \ | |
101 /mnt/stateful_partition/home/chronos/user/crash" | |
102 local remote_crash_patterns="" | |
103 for remote_crash_dir in ${remote_crash_dirs}; do | |
104 remote_crash_patterns="${remote_crash_patterns} \ | |
105 ${remote_crash_dir}/*.{dmp,kcrash}" | |
106 done | |
107 remote_sh "ls -1 ${remote_crash_patterns}" 2> /dev/null | |
108 local crashes=${REMOTE_OUT} | |
109 # Remove duplicates. | |
110 local unique_crashes="" | |
111 local crash_count=0 | |
112 for crash in ${crashes}; do | |
113 local crash_short=$(basename ${crash}) | |
114 if echo "${unique_crashes}" | grep -v -q "${crash_short}"; then | |
115 unique_crashes="${unique_crashes} ${crash}" | |
116 crash_count=$((crash_count + 1)) | |
117 fi | |
118 done | |
119 if [ ${crash_count} -eq 0 ]; then | |
120 info "No crashes found on device." | |
121 exit 0 | |
122 fi | |
123 info "Copying back ${crash_count} crashes." | |
124 crashes="${unique_crashes}" | |
125 local filesfrom="${TMP}/filesfrom" | |
126 FLAGS_ARGV="" | |
127 for crash in ${crashes}; do | |
128 echo "${crash}" >> "${filesfrom}" | |
129 FLAGS_ARGV="${FLAGS_ARGV} '${TMP}/$(basename ${crash})'" | |
130 done | |
131 remote_rsync_from "${filesfrom}" "${TMP}" | |
132 if [ ${FLAGS_clean} -eq ${FLAGS_TRUE} ]; then | |
133 remote_sh "rm -rf ${remote_crash_dirs}" | |
134 fi | |
135 else | |
136 [ -n "${FLAGS_ARGV}" ] || usage | |
137 [ -n "${FLAGS_board}" ] || die "--board is required." | |
138 fi | |
139 | |
140 local modules_file="${TMP}/modules" | |
141 for dump in ${FLAGS_ARGV}; do | |
142 dump=$(remove_quotes "${dump}") | |
143 if [ $(get_kind "${dump}") == "minidump" ]; then | |
144 # Find all DSOs and executables listed in lines like: | |
145 # (code_file) = "/usr/lib/mylib.so" | |
146 ${MINIDUMP_DUMP} "${dump}" 2>/dev/null \ | |
147 | grep code_file \ | |
148 | sed 's/.*= "\(.*\)"/\1/' \ | |
149 >> "${modules_file}" | |
150 fi | |
151 done | |
152 | |
153 if [ -z "${FLAGS_breakpad_root}" ]; then | |
154 generate_symbols "${modules_file}" | |
155 FLAGS_breakpad_root=/build/${FLAGS_board}/usr/lib/debug/breakpad | |
156 fi | |
157 | |
158 for dump in ${FLAGS_ARGV}; do | |
159 dump=$(remove_quotes "${dump}") | |
160 if [ $(get_kind "${dump}") = "minidump" ]; then | |
161 info "Dumping stack for $(basename ${dump}) with ${FLAGS_breakpad_root}:" | |
162 ${MINIDUMP_STACKWALK} "${dump}" "${FLAGS_breakpad_root}" 2> /dev/null | |
163 else | |
164 info "Dumping kcrash $(basename ${dump}):" | |
165 cat "${dump}" | |
166 fi | |
167 echo "" | |
168 done | |
169 } | |
170 | |
171 main "$@" | |
OLD | NEW |