| OLD | NEW |
| 1 #!/bin/sh | 1 #!/bin/sh |
| 2 | 2 |
| 3 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved. | 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 | 4 # Use of this source code is governed by a BSD-style license that can be |
| 5 # found in the LICENSE file. | 5 # found in the LICENSE file. |
| 6 | 6 |
| 7 set -e | 7 set -e |
| 8 | 8 |
| 9 # Product ID in crash report | 9 # Product ID in crash report |
| 10 CHROMEOS_PRODUCT=ChromeOS | 10 CHROMEOS_PRODUCT=ChromeOS |
| 11 | 11 |
| 12 # File whose existence implies crash reports may be sent, and whose |
| 13 # contents includes our machine's anonymized guid. |
| 14 CONSENT_ID="/home/chronos/Consent To Send Stats" |
| 15 |
| 12 # Send up to 8 crashes per day. | 16 # Send up to 8 crashes per day. |
| 13 MAX_CRASH_RATE=8 | 17 MAX_CRASH_RATE=8 |
| 14 | 18 |
| 15 # Minidump uploading tool (provided by Google Breakpad). | |
| 16 MINIDUMP_UPLOADER=/usr/bin/minidump_upload | |
| 17 | |
| 18 # URL to send non-official build crashes to. | 19 # URL to send non-official build crashes to. |
| 19 MINIDUMP_UPLOAD_STAGING_URL="http://clients2.google.com/cr/staging_report" | 20 MINIDUMP_UPLOAD_STAGING_URL="http://clients2.google.com/cr/staging_report" |
| 20 | 21 |
| 21 # URL to send official build crashes to. | 22 # URL to send official build crashes to. |
| 22 MINIDUMP_UPLOAD_PROD_URL="http://clients2.google.com/cr/report" | 23 MINIDUMP_UPLOAD_PROD_URL="http://clients2.google.com/cr/report" |
| 23 | 24 |
| 24 # File whose existence mocks crash sending. If empty we pretend the | 25 # File whose existence mocks crash sending. If empty we pretend the |
| 25 # crash sending was successful, otherwise unsuccessful. | 26 # crash sending was successful, otherwise unsuccessful. |
| 26 MOCK_CRASH_SENDING="/tmp/mock-crash-sending" | 27 MOCK_CRASH_SENDING="/tmp/mock-crash-sending" |
| 27 | 28 |
| 28 # File whose existence causes crash sending to be delayed (for testing). | 29 # File whose existence causes crash sending to be delayed (for testing). |
| 29 PAUSE_CRASH_SENDING="/tmp/pause-crash-sending" | 30 PAUSE_CRASH_SENDING="/tmp/pause-crash-sending" |
| 30 | 31 |
| 31 # File whose existence implies we're running and not to start again. | 32 # File whose existence implies we're running and not to start again. |
| 32 RUN_FILE="/var/run/crash_sender.pid" | 33 RUN_FILE="/var/run/crash_sender.pid" |
| 33 | 34 |
| 34 # Maximum time to sleep between sends. | 35 # Maximum time to sleep between sends. |
| 35 SECONDS_SEND_SPREAD=600 | 36 SECONDS_SEND_SPREAD=${SECONDS_SEND_SPREAD:-600} |
| 36 | 37 |
| 37 # The syslog tag for all logging we emit. | 38 # The syslog tag for all logging we emit. |
| 38 TAG="$(basename $0)[$$]" | 39 TAG="$(basename $0)[$$]" |
| 39 | 40 |
| 40 # Directory to store timestamp files indicating the uploads in the past 24 | 41 # Directory to store timestamp files indicating the uploads in the past 24 |
| 41 # hours. | 42 # hours. |
| 42 TIMESTAMPS_DIR="/var/lib/crash_sender" | 43 TIMESTAMPS_DIR="/var/lib/crash_sender" |
| 43 | 44 |
| 44 lecho() { | 45 lecho() { |
| 45 logger -t "${TAG}" "$@" | 46 logger -t "${TAG}" "$@" |
| 46 } | 47 } |
| 47 | 48 |
| 48 remove_run_file() { | 49 log_done() { |
| 50 lecho "Done" |
| 51 } |
| 52 |
| 53 cleanup_tmp_dir() { |
| 54 rm -rf "${TMP_DIR}" |
| 55 log_done |
| 56 } |
| 57 |
| 58 cleanup_run_file_and_tmp_dir() { |
| 49 rm -f "${RUN_FILE}" | 59 rm -f "${RUN_FILE}" |
| 60 cleanup_tmp_dir |
| 50 } | 61 } |
| 51 | 62 |
| 52 check_not_already_running() { | 63 check_not_already_running() { |
| 53 if [ ! -f "${RUN_FILE}" ]; then | 64 if [ ! -f "${RUN_FILE}" ]; then |
| 54 return | 65 return |
| 55 fi | 66 fi |
| 56 local last_pid=$(cat "${RUN_FILE}") | 67 local last_pid=$(cat "${RUN_FILE}") |
| 57 if [ ! -f "/proc/${last_pid}/cmdline" ]; then | 68 if [ ! -f "/proc/${last_pid}/cmdline" ]; then |
| 58 trap remove_run_file EXIT | 69 trap cleanup_run_file_and_tmp_dir EXIT INT |
| 59 echo $$ > "${RUN_FILE}" | 70 echo $$ > "${RUN_FILE}" |
| 60 return | 71 return |
| 61 fi | 72 fi |
| 62 # This could just be an unrelated process, but it's ok to be conservative. | 73 # This could just be an unrelated process, but it's ok to be conservative. |
| 63 lecho "Already running. Exiting now." | 74 lecho "Already running. Exiting now." |
| 64 exit 1 | 75 exit 1 |
| 65 } | 76 } |
| 66 | 77 |
| 67 get_version() { | 78 get_version() { |
| 68 grep ^CHROMEOS_RELEASE_VERSION /etc/lsb-release | cut -d = -f 2- | 79 grep ^CHROMEOS_RELEASE_VERSION /etc/lsb-release | cut -d = -f 2- |
| 69 } | 80 } |
| 70 | 81 |
| 71 is_official() { | 82 is_official() { |
| 72 grep ^CHROMEOS_RELEASE_DESCRIPTION /etc/lsb-release | cut -d = -f 2- | \ | 83 grep ^CHROMEOS_RELEASE_DESCRIPTION /etc/lsb-release | cut -d = -f 2- | \ |
| 73 grep Official | 84 grep Official |
| 74 } | 85 } |
| 75 | 86 |
| 76 # Generate a uniform random number in 0..max-1. | 87 # Generate a uniform random number in 0..max-1. |
| 77 generate_uniform_random() { | 88 generate_uniform_random() { |
| 78 local max=$1 | 89 local max=$1 |
| 79 local random="$(od -An -N4 -tu /dev/urandom)" | 90 local random="$(od -An -N4 -tu /dev/urandom)" |
| 80 echo $((random % max)) | 91 echo $((random % max)) |
| 81 } | 92 } |
| 82 | 93 |
| 83 is_feedback_disabled() { | 94 is_feedback_disabled() { |
| 84 # See crosbug.com/3303. | 95 [ -r "${CONSENT_ID}" ] && return 1 |
| 85 return 1 | 96 return 0 |
| 86 } | 97 } |
| 87 | 98 |
| 88 is_on_3g() { | 99 is_on_3g() { |
| 89 # See crosbug.com/3304. | 100 # See crosbug.com/3304. |
| 90 return 1 | 101 return 1 |
| 91 } | 102 } |
| 92 | 103 |
| 93 # Check if sending a crash now does not exceed the maximum 24hr rate and | 104 # Check if sending a crash now does not exceed the maximum 24hr rate and |
| 94 # commit to doing so, if not. | 105 # commit to doing so, if not. |
| 95 check_rate() { | 106 check_rate() { |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 137 lecho "Mocking unsuccessful send" | 148 lecho "Mocking unsuccessful send" |
| 138 return 1 | 149 return 1 |
| 139 fi | 150 fi |
| 140 fi | 151 fi |
| 141 | 152 |
| 142 if ! sleep ${sleep_time}; then | 153 if ! sleep ${sleep_time}; then |
| 143 lecho "Sleep failed" | 154 lecho "Sleep failed" |
| 144 return 1 | 155 return 1 |
| 145 fi | 156 fi |
| 146 | 157 |
| 147 "${MINIDUMP_UPLOADER}" -p "${CHROMEOS_PRODUCT}" \ | 158 local report_id="${TMP_DIR}/report_id" |
| 148 -v "${chromeos_version}" "${minidump_path}" "${url}" | 159 local curl_stderr="${TMP_DIR}/curl_stderr" |
| 149 return $? | 160 |
| 161 set +e |
| 162 curl "${url}" \ |
| 163 -F "prod=${CHROMEOS_PRODUCT}" \ |
| 164 -F "ver=${chromeos_version}" \ |
| 165 -F "upload_file_minidump=@${minidump_path}" \ |
| 166 -F "guid=<${CONSENT_ID}" -o "${report_id}" 2>"${curl_stderr}" |
| 167 local curl_result=$? |
| 168 set -e |
| 169 |
| 170 if [ ${curl_result} -eq 0 ]; then |
| 171 lecho "Crash report receipt ID $(cat ${report_id})" |
| 172 else |
| 173 lecho "Crash sending failed with: $(cat ${curl_stderr})" |
| 174 fi |
| 175 |
| 176 rm -f "${report_id}" "${output_file}" |
| 177 |
| 178 return ${curl_result} |
| 150 } | 179 } |
| 151 | 180 |
| 152 # Send all crashes from the given directory. The directory is currently | 181 # Send all crashes from the given directory. The directory is currently |
| 153 # expected to just contain a bunch of minidumps - but this will change | 182 # expected to just contain a bunch of minidumps. |
| 154 # over time to be a directory of directories where the minidump and core | |
| 155 # file are in the directory as well as other metadata about the context | |
| 156 # of the crash (executable name for instance). | |
| 157 send_crashes() { | 183 send_crashes() { |
| 158 local dir="$1" | 184 local dir="$1" |
| 159 lecho "Considering crashes in ${dir}" | 185 lecho "Considering crashes in ${dir}" |
| 160 # Cycle through minidumps, most recent first. That way if we're about | 186 # Cycle through minidumps, most recent first. That way if we're about |
| 161 # to exceed the daily rate, we send the most recent minidumps. | 187 # to exceed the daily rate, we send the most recent minidumps. |
| 162 if [ ! -d "${dir}" ]; then | 188 if [ ! -d "${dir}" ]; then |
| 163 return | 189 return |
| 164 fi | 190 fi |
| 165 for file in $(ls -1t "${dir}"); do | 191 for file in $(ls -1t "${dir}"); do |
| 166 local minidump_path="${dir}/${file}" | 192 local minidump_path="${dir}/${file}" |
| (...skipping 13 matching lines...) Expand all Loading... |
| 180 lecho "Successfully sent crash ${minidump_path} and removing" | 206 lecho "Successfully sent crash ${minidump_path} and removing" |
| 181 rm "${minidump_path}" | 207 rm "${minidump_path}" |
| 182 else | 208 else |
| 183 lecho "Problem sending ${minidump_path}, not removing" | 209 lecho "Problem sending ${minidump_path}, not removing" |
| 184 fi | 210 fi |
| 185 done | 211 done |
| 186 } | 212 } |
| 187 | 213 |
| 188 main() { | 214 main() { |
| 189 lecho "Starting" | 215 lecho "Starting" |
| 216 trap log_done EXIT INT |
| 217 |
| 190 if [ -e "${PAUSE_CRASH_SENDING}" ]; then | 218 if [ -e "${PAUSE_CRASH_SENDING}" ]; then |
| 191 lecho "Exiting early due to ${PAUSE_CRASH_SENDING}" | 219 lecho "Exiting early due to ${PAUSE_CRASH_SENDING}" |
| 192 exit 1 | 220 exit 1 |
| 193 fi | 221 fi |
| 194 | 222 |
| 195 check_not_already_running | 223 check_not_already_running |
| 196 | 224 |
| 225 TMP_DIR="$(mktemp -d /tmp/crash_sender.XXXX)" |
| 226 trap cleanup_tmp_dir EXIT INT |
| 227 |
| 197 # Send system-wide crashes | 228 # Send system-wide crashes |
| 198 send_crashes "/var/spool/crash" | 229 send_crashes "/var/spool/crash" |
| 199 | 230 |
| 200 # Send user-specific crashes | 231 # Send user-specific crashes |
| 201 send_crashes "/home/chronos/user/crash" | 232 send_crashes "/home/chronos/user/crash" |
| 202 | |
| 203 lecho "Done" | |
| 204 } | 233 } |
| 205 | 234 |
| 206 main | 235 main |
| OLD | NEW |