OLD | NEW |
(Empty) | |
| 1 #!/bin/bash |
| 2 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved. |
| 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. |
| 5 |
| 6 # Script to upload all debug symbols required for crash reporting |
| 7 # purposes. This script need only be used to upload release builds |
| 8 # symbols or to debug crashes on non-release builds (in which case try |
| 9 # to only upload the symbols for those executables involved). |
| 10 # |
| 11 # NOTE: This script must be run from the chromeos build chroot environment. |
| 12 # |
| 13 |
| 14 # Load common constants. This should be the first executable line. |
| 15 # The path to common.sh should be relative to your script's location. |
| 16 . "$(dirname "$0")/common.sh" |
| 17 |
| 18 # Script must be run inside the chroot |
| 19 restart_in_chroot_if_needed $* |
| 20 |
| 21 get_default_board |
| 22 |
| 23 # Flags |
| 24 DEFINE_string board "$DEFAULT_BOARD" "The board to build packages for." |
| 25 DEFINE_boolean dryrun ${FLAGS_FALSE} "Run without actually uploading." |
| 26 DEFINE_boolean verbose ${FLAGS_FALSE} "Be verbose." |
| 27 DEFINE_boolean yes ${FLAGS_FALSE} "Answer yes to all prompts." |
| 28 |
| 29 DUMP_SYMS="dump_syms.i386" |
| 30 SYM_UPLOAD="sym_upload.i386" |
| 31 |
| 32 CUMULATIVE_SIZE=0 |
| 33 |
| 34 SYM_FILE=$(mktemp "/tmp/sym.XXXX") |
| 35 ERR_FILE=$(mktemp "/tmp/err.XXXX") |
| 36 |
| 37 function cleanup() { |
| 38 rm -f "${SYM_FILE}" "${ERR_FILE}" |
| 39 } |
| 40 |
| 41 function is_official() { |
| 42 if [ ${CHROMEOS_OFFICIAL:-0} = 1 ]; then |
| 43 return 0 |
| 44 else |
| 45 return 1 |
| 46 fi |
| 47 } |
| 48 |
| 49 # Given path to a debug file, return its text file |
| 50 function get_text_for_debug { |
| 51 local debug_file=$1 |
| 52 local text_dir=$(dirname ${debug_file#$DEBUG_ROOT}) |
| 53 local text_path=${SYSROOT}${text_dir}/$(basename "${debug_file}" .debug) |
| 54 echo ${text_path} |
| 55 } |
| 56 |
| 57 # Given path to a text file, return its debug file |
| 58 function get_debug_for_text { |
| 59 local text_file=$1 |
| 60 local text_path=${text_file#${SYSROOT}} |
| 61 local debug_path=${DEBUG_ROOT}${text_path}.debug |
| 62 echo ${debug_path} |
| 63 } |
| 64 |
| 65 function really_upload { |
| 66 if [ ${FLAGS_yes} -eq ${FLAGS_TRUE} ]; then |
| 67 return 0 |
| 68 fi |
| 69 echo "Uploading symbols for an entire Chromium OS build is really only " |
| 70 echo "necessary for release builds and in a few cases for developers " |
| 71 echo "to debug problems. It will take considerable time to run. For " |
| 72 echo "developer debugging purposes, consider instead passing specific files " |
| 73 echo "to upload." |
| 74 read -p "Are you sure you want to upload all build symbols (y/N)? " SURE |
| 75 SURE="${SURE:0:1}" # Get just the first character |
| 76 if [ "${SURE}" != "y" ]; then |
| 77 echo "Ok, better safe than sorry." |
| 78 return 1 |
| 79 fi |
| 80 return 0 |
| 81 } |
| 82 |
| 83 function dump_file { |
| 84 local debug_file="$1" |
| 85 local text_file="$2" |
| 86 # Dump symbols as root in order to read all files. |
| 87 if ! sudo "${DUMP_SYMS}" "${debug_file}" "${text_file}" > "${SYM_FILE}" \ |
| 88 2> "${ERR_FILE}"; then |
| 89 # A lot of files (like kernel files) contain no debug information, do |
| 90 # not consider such occurrences as errors. |
| 91 if grep -q "file contains no debugging information" "${ERR_FILE}"; then |
| 92 warn "No symbols found for ${text_file}" |
| 93 return 0 |
| 94 fi |
| 95 error "Unable to dump symbols for ${text_file}:" |
| 96 cat "${ERR_FILE}" |
| 97 return 1 |
| 98 fi |
| 99 if [ ${FLAGS_verbose} -eq ${FLAGS_TRUE} ]; then |
| 100 local file_id=$(head -1 ${SYM_FILE} | cut -d' ' -f4) |
| 101 local module_name=$(head -1 ${SYM_FILE} | cut -d' ' -f5) |
| 102 # Show file upload success and symbol info for easier lookup |
| 103 info "Dumped symbols from ${text_file} for ${module_name}|${file_id}." |
| 104 fi |
| 105 # Sanity check: if we've created the same named file in the /usr/lib/debug |
| 106 # directory during the src_compile stage of an ebuild, verify our sym file |
| 107 # is the same. |
| 108 local installed_sym="${DEBUG_ROOT}"/$(basename "${text_file}").sym |
| 109 if [ -e "${installed_sym}" ]; then |
| 110 if ! diff "${installed_sym}" "${SYM_FILE}"; then |
| 111 error "${installed_sym} differ from current sym file:" |
| 112 diff "${installed_sym}" "${SYM_FILE}" |
| 113 return 1 |
| 114 fi |
| 115 fi |
| 116 size=$(wc -c "${SYM_FILE}" | cut -d' ' -f1) |
| 117 CUMULATIVE_SIZE=$((CUMULATIVE_SIZE + $size)) |
| 118 return 0 |
| 119 } |
| 120 |
| 121 # Upload the current symbol file to given URL. |
| 122 function upload_file { |
| 123 local upload_url="$1" |
| 124 if ! "${SYM_UPLOAD}" "${SYM_FILE}" "${upload_url}" > /dev/null \ |
| 125 2> "${ERR_FILE}"; then |
| 126 error "Unable to upload symbols in ${SYM_FILE}:" |
| 127 cat "${ERR_FILE}" |
| 128 return 1 |
| 129 fi |
| 130 if [ ${FLAGS_verbose} -eq ${FLAGS_TRUE} ]; then |
| 131 size=$(wc -c "${SYM_FILE}" | cut -d' ' -f1) |
| 132 info "Successfully uploaded ${size}B." |
| 133 fi |
| 134 return 0 |
| 135 } |
| 136 |
| 137 # Convert and then upload the given debug file to the given URL. |
| 138 function process_file { |
| 139 local debug_file="$1" |
| 140 local upload_url="$2" |
| 141 local text_file="$(get_text_for_debug ${debug_file})" |
| 142 if [ "${text_file##*.}" == "ko" ]; then |
| 143 # Skip kernel objects. We can't use their symbols and they sometimes |
| 144 # have objects with empty text sections which trigger errors in dump_sym. |
| 145 if [ ${FLAGS_verbose} -eq ${FLAGS_TRUE} ]; then |
| 146 info "Skipping kernel object: ${text_file}" |
| 147 fi |
| 148 return 0 |
| 149 fi |
| 150 if [ "${text_file#${AUTOTEST_ROOT}}" != "${text_file}" ]; then |
| 151 # Skip autotest files, they are not part of the image to debug |
| 152 # and some cause trouble to dump_syms because they are built |
| 153 # externally (with different build options). |
| 154 if [ ${FLAGS_verbose} -eq ${FLAGS_TRUE} ]; then |
| 155 info "Skipping autotest file: ${text_file}" |
| 156 fi |
| 157 return 0 |
| 158 fi |
| 159 if [ ! -f "${text_file}" ]; then |
| 160 # Allow files to not exist, for instance if they are in the INSTALL_MASK. |
| 161 warn "Binary does not exist: ${text_file}" |
| 162 return 0 |
| 163 fi |
| 164 |
| 165 dump_file "${debug_file}" "${text_file}" || return 1 |
| 166 |
| 167 [ ${FLAGS_dryrun} -eq ${FLAGS_TRUE} ] && return 0 |
| 168 |
| 169 upload_file "${upload_url}" |
| 170 } |
| 171 |
| 172 function main() { |
| 173 trap cleanup EXIT |
| 174 |
| 175 # Parse command line |
| 176 FLAGS_HELP="usage: $0 [flags] [<files...>]" |
| 177 FLAGS "$@" || exit 1 |
| 178 eval set -- "${FLAGS_ARGV}" |
| 179 |
| 180 set -e |
| 181 |
| 182 [ -n "$FLAGS_board" ] || die "--board is required." |
| 183 |
| 184 SYSROOT="/build/${FLAGS_board}" |
| 185 |
| 186 local upload_url="" |
| 187 if [ ${FLAGS_dryrun} -eq ${FLAGS_FALSE} ]; then |
| 188 if is_official; then |
| 189 upload_url="http://clients2.google.com/cr/symbol" |
| 190 else |
| 191 upload_url="http://clients2.google.com/cr/staging_symbol" |
| 192 warn "This is an unofficial build, uploading to staging server." |
| 193 fi |
| 194 info "Uploading symbols to ${upload_url} from ${SYSROOT}." |
| 195 else |
| 196 warn "Will not upload symbols due to --nodryrun." |
| 197 fi |
| 198 |
| 199 DEBUG_ROOT="${SYSROOT}/usr/lib/debug" |
| 200 AUTOTEST_ROOT="${SYSROOT}/usr/local/autotest" |
| 201 CUMULATIVE_SIZE=0 |
| 202 |
| 203 local any_errors=0 |
| 204 if [ -z "${FLAGS_ARGV}" ]; then |
| 205 if [ ${FLAGS_dryrun} -eq ${FLAGS_FALSE} ]; then |
| 206 really_upload || exit 1 |
| 207 fi |
| 208 for debug_file in $(find "${DEBUG_ROOT}" -name \*.debug); do |
| 209 if ! process_file "${debug_file}" "${upload_url}"; then |
| 210 any_errors=1 |
| 211 fi |
| 212 done |
| 213 else |
| 214 for either_file in ${FLAGS_ARGV}; do |
| 215 either_file=${either_file#\'} |
| 216 either_file=${either_file%\'} |
| 217 if [ ! -f "${either_file}" ]; then |
| 218 error "Specified file ${either_file} does not exist" |
| 219 any_errors=1 |
| 220 continue |
| 221 fi |
| 222 if [ "${either_file##*.}" == "debug" ]; then |
| 223 debug_file="${either_file}" |
| 224 else |
| 225 debug_file="$(get_debug_for_text ${either_file})" |
| 226 fi |
| 227 if ! process_file "${debug_file}" "${upload_url}"; then |
| 228 any_errors=1 |
| 229 fi |
| 230 done |
| 231 fi |
| 232 |
| 233 if [ ${FLAGS_dryrun} -eq ${FLAGS_TRUE} ]; then |
| 234 warn "Did not actually upload, pass --nodryrun to upload" |
| 235 info "Would have uploaded ${CUMULATIVE_SIZE}B of debug information" |
| 236 else |
| 237 info "Uploaded ${CUMULATIVE_SIZE}B of debug information" |
| 238 fi |
| 239 [ ${any_errors} -ne 0 ] && die "Encountered problems" |
| 240 } |
| 241 |
| 242 main "$@" |
OLD | NEW |