Chromium Code Reviews| 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 |