flatcar-scripts/cros_generate_breakpad_symbols
Michael Krebs 68da4439ff Don't try to generate symbols for symbolic links
In our build environment, we have lots of symbolic links such as
"debug/.build-id/5c/a06545ff3812557dc5fd259db4e905c5dc3484.debug" that just
link to another .debug file.  In our case, those links don't actually point
to the right place, so we've just been seeing lots of "Binary does not
exist" warnings.  But it would also be undesirable to actually generate
symbols for these even if their targets *did* exist.

BUG=None
TEST=Ran cros_generate_breakpad_symbols

Change-Id: I050c349f7fefbdf922d54250379bad9b3db073d7
Reviewed-on: https://gerrit.chromium.org/gerrit/19182
Commit-Ready: Michael Krebs <mkrebs@chromium.org>
Tested-by: Michael Krebs <mkrebs@chromium.org>
Reviewed-by: David James <davidjames@chromium.org>
2012-03-27 16:44:22 -07:00

207 lines
6.5 KiB
Bash
Executable File

#!/bin/bash
# Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# Script to generate minidump symbols in the format required by
# minidump_stackwalk to dump stack information.
#
# NOTE: This script must be run from the chromeos build chroot environment.
#
SCRIPT_ROOT=$(dirname $(readlink -f "$0"))
. "${SCRIPT_ROOT}/common.sh" || { echo "Unable to load common.sh"; exit 1; }
# Script must be run inside the chroot
restart_in_chroot_if_needed "$@"
get_default_board
# Flags
DEFINE_string board "$DEFAULT_BOARD" "The board to build packages for."
DEFINE_string minidump_symbol_root "" \
"Symbol root (defaults to /usr/lib/debug/breakpad for board)"
DEFINE_boolean verbose ${FLAGS_FALSE} "Be verbose."
DUMP_SYMS="dump_syms"
DUMP_SYMS32="dump_syms.32"
CUMULATIVE_SIZE=0
ANY_ERRORS=0
SYM_FILE=$(mktemp "/tmp/sym.XXXX")
ERR_FILE=$(mktemp "/tmp/err.XXXX")
function cleanup() {
rm -f "${SYM_FILE}" "${ERR_FILE}"
}
# Given path to a debug file, return its text file
function get_text_for_debug() {
local debug_file=$1
local text_dir=$(dirname "${debug_file#$DEBUG_ROOT}")
local text_path=${SYSROOT}${text_dir}/$(basename "${debug_file}" .debug)
echo ${text_path}
}
# Given path to a text file, return its debug file
function get_debug_for_text() {
local text_file=$1
local text_path=${text_file#${SYSROOT}}
local debug_path=${DEBUG_ROOT}${text_path}.debug
echo ${debug_path}
}
# Returns true if the file given is a 32-bit ELF file.
function is_32b_elf() {
local elf="$1"
file "${elf}" | grep -q "ELF 32-bit"
}
# Dump given debug and text file. Returns 1 if any errors, even
# if they can be ignored, but only sets ANY_ERRORS if the error should not
# be ignored (and we should not proceed to upload).
function dump_file() {
local debug_file="$1"
local text_file="$2"
local debug_directory="$(dirname "${debug_file}")"
local dump_syms_prog="${DUMP_SYMS}"
# 32-bit dump_syms must be used to dump a 32-bit ELF file
if is_32b_elf "${text_file}"; then
dump_syms_prog="${DUMP_SYMS32}"
info "Using ${dump_syms_prog} for 32-bit file ${text_file}"
fi
# Dump symbols as root in order to read all files.
if ! sudo "${dump_syms_prog}" "${text_file}" "${debug_directory}" \
> "${SYM_FILE}" 2> "${ERR_FILE}"; then
# Try dumping just the main file to get public-only symbols.
if ! sudo "${dump_syms_prog}" "${text_file}" > "${SYM_FILE}" \
2> "${ERR_FILE}"; then
# A lot of files (like kernel files) contain no debug information, do
# not consider such occurrences as errors.
if grep -q "file contains no debugging information" "${ERR_FILE}"; then
warn "No symbols found for ${text_file}"
return 1
fi
error "Unable to dump symbols for ${text_file}:"
cat "${ERR_FILE}"
ANY_ERRORS=1
return 1
else
warn "File ${text_file} did not have debug info, using linkage symbols"
fi
fi
local file_id=$(head -1 ${SYM_FILE} | cut -d' ' -f4)
local module_name=$(head -1 ${SYM_FILE} | cut -d' ' -f5)
if [ ${FLAGS_verbose} -eq ${FLAGS_TRUE} ]; then
# Show file upload success and symbol info for easier lookup
info "Dumped symbols from ${text_file} for ${module_name}|${file_id}."
fi
# Sanity check: if we've created the same named file in the /usr/lib/debug
# directory during the src_compile stage of an ebuild, verify our sym file
# is the same.
local installed_sym="${DEBUG_ROOT}"/$(basename "${text_file}").sym
if [ -e "${installed_sym}" ]; then
if ! diff "${installed_sym}" "${SYM_FILE}"; then
error "${installed_sym} differ from current sym file:"
diff "${installed_sym}" "${SYM_FILE}"
ANY_ERRORS=1
return 1
fi
fi
size=$(wc -c "${SYM_FILE}" | cut -d' ' -f1)
CUMULATIVE_SIZE=$((CUMULATIVE_SIZE + $size))
local container_dir="${FLAGS_minidump_symbol_root}/${module_name}/${file_id}"
sudo mkdir -p "${container_dir}"
sudo mv "${SYM_FILE}" "${container_dir}/${module_name}.sym"
return 0
}
# Convert the given debug file. No return value.
function process_file() {
local debug_file="$1"
local text_file="$(get_text_for_debug ${debug_file})"
if [ -h "${debug_file}" ]; then
# Don't follow symbolic links. In particular, we don't want to bother
# with the *.debug links in the "debug/.build-id/" directory.
if [ ${FLAGS_verbose} -eq ${FLAGS_TRUE} ]; then
info "Skipping symbolic link: ${debug_file}"
fi
return 0
fi
if [ "${text_file##*.}" == "ko" ]; then
# Skip kernel objects. We can't use their symbols and they sometimes
# have objects with empty text sections which trigger errors in dump_sym.
if [ ${FLAGS_verbose} -eq ${FLAGS_TRUE} ]; then
info "Skipping kernel object: ${text_file}"
fi
return 0
fi
if [ ! -f "${text_file}" ]; then
# Allow files to not exist, for instance if they are in the INSTALL_MASK.
warn "Binary does not exist: ${text_file}"
return 0
elif [ ! -r "${text_file}" ]; then
# Allow files to not be readable, for instance setuid programs like passwd
warn "Binary is not readable: ${text_file}"
return 0
fi
dump_file "${debug_file}" "${text_file}"
}
function main() {
trap cleanup EXIT
# Parse command line
FLAGS_HELP="usage: $0 [flags] [<files...>]"
FLAGS "$@" || exit 1
eval set -- "${FLAGS_ARGV}"
set -e
[ -n "$FLAGS_board" ] || die "--board is required."
SYSROOT="/build/${FLAGS_board}"
if [[ -z "${FLAGS_minidump_symbol_root}" ]]; then
FLAGS_minidump_symbol_root="${SYSROOT}/usr/lib/debug/breakpad"
fi
info "Writing minidump symbols to ${FLAGS_minidump_symbol_root}"
DEBUG_ROOT="${SYSROOT}/usr/lib/debug"
CUMULATIVE_SIZE=0
sudo rm -rf "${FLAGS_minidump_symbol_root}"
if [ -z "${FLAGS_ARGV}" ]; then
for debug_file in $(find "${DEBUG_ROOT}" -name \*.debug); do
! process_file "${debug_file}"
done
else
for either_file in ${FLAGS_ARGV}; do
either_file=${either_file#\'}
either_file=${either_file%\'}
if [ ! -h "${either_file}" -a ! -f "${either_file}" ]; then
error "Specified file ${either_file} does not exist"
ANY_ERRORS=1
continue
fi
if [ "${either_file##*.}" == "debug" ]; then
debug_file="${either_file}"
else
debug_file="$(get_debug_for_text ${either_file})"
fi
! process_file "${debug_file}"
done
fi
info "Generated ${CUMULATIVE_SIZE}B of debug information"
[ ${ANY_ERRORS} -ne 0 ] && die "Encountered problems"
return 0
}
main "$@"