Caroline Tice | 3250e19 | 2011-09-19 23:33:46 | [diff] [blame] | 1 | #!/bin/bash |
| 2 | |
| 3 | # Copyright (c) 2011 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 | |
David James | 7c2e2f7 | 2012-07-10 17:17:10 | [diff] [blame] | 7 | . /usr/lib/crosutils/common.sh || exit 1 |
Caroline Tice | 3250e19 | 2011-09-19 23:33:46 | [diff] [blame] | 8 | |
Caroline Tice | 3250e19 | 2011-09-19 23:33:46 | [diff] [blame] | 9 | # Flags |
Ken Mixter | 1853cc2 | 2011-11-19 02:20:27 | [diff] [blame] | 10 | DEFINE_string attach "" \ |
| 11 | "pgrep for the given command - 'browser' finds the chrome browser process" |
Caroline Tice | 3250e19 | 2011-09-19 23:33:46 | [diff] [blame] | 12 | DEFINE_string board "${DEFAULT_BOARD}" \ |
| 13 | "The board to run debugger on." |
Caroline Tice | 6dc7201 | 2011-10-20 17:23:50 | [diff] [blame] | 14 | DEFINE_string remote "localhost" \ |
Caroline Tice | 3250e19 | 2011-09-19 23:33:46 | [diff] [blame] | 15 | "The IP address of the remote device." |
| 16 | DEFINE_integer port 1234 \ |
| 17 | "The port number to use for connecting to remote device." |
| 18 | DEFINE_integer remote_pid 0 \ |
| 19 | "Process ID of the running process on the remote device to which to attach." |
| 20 | DEFINE_string remote_file "" \ |
| 21 | "Full pathname of the file to be debugged on the remote device." |
| 22 | |
| 23 | # Parse command line |
| 24 | FLAGS_HELP="usage: $0 [flags]" |
| 25 | FLAGS "$@" || exit 1 |
| 26 | eval set -- "${FLAGS_ARGV}" |
| 27 | check_flags_only_and_allow_null_arg "$@" && set -- |
| 28 | |
| 29 | BOARD=${FLAGS_board} |
| 30 | BOARD_ROOT=/build/${BOARD} |
| 31 | |
| 32 | # Derive toolchain from $BOARD |
| 33 | CHOST=$(portageq-${BOARD} envvar CHOST) |
| 34 | |
Caroline Tice | cce25bd | 2011-10-07 22:45:52 | [diff] [blame] | 35 | TMP_DIR="" |
| 36 | SSH_PID=0 |
| 37 | CLEAN=0 |
Ahmad Sharif | cf1615e | 2011-11-15 21:53:01 | [diff] [blame] | 38 | GDBINIT_FILE=~/.gdbinit |
Caroline Tice | cce25bd | 2011-10-07 22:45:52 | [diff] [blame] | 39 | |
| 40 | cleanup () |
| 41 | { |
| 42 | if [ ${CLEAN} -eq 0 ] ; then |
| 43 | rm -rf ${TMP_DIR} |
| 44 | if [ ${SSH_PID} -ne 0 ] ; then |
| 45 | kill ${SSH_PID} |
| 46 | fi |
| 47 | CLEAN=1 |
| 48 | fi |
Ahmad Sharif | cf1615e | 2011-11-15 21:53:01 | [diff] [blame] | 49 | rm -rf ${GDBINIT_FILE} |
Caroline Tice | cce25bd | 2011-10-07 22:45:52 | [diff] [blame] | 50 | } |
| 51 | |
Caroline Tice | 3250e19 | 2011-09-19 23:33:46 | [diff] [blame] | 52 | # Create a temporary location in which to copy testing_rsa file; make |
| 53 | # sure to clean it up when we exit. |
| 54 | |
Caroline Tice | cce25bd | 2011-10-07 22:45:52 | [diff] [blame] | 55 | trap 'cleanup' EXIT INT TERM |
Caroline Tice | 3250e19 | 2011-09-19 23:33:46 | [diff] [blame] | 56 | TMP_DIR=$(mktemp -d) |
| 57 | |
| 58 | cp ${SCRIPTS_DIR}/mod_for_test_scripts/ssh_keys/testing_rsa \ |
| 59 | ${TMP_DIR}/testing_rsa |
| 60 | chmod 0600 ${TMP_DIR}/testing_rsa |
| 61 | |
Caroline Tice | cce25bd | 2011-10-07 22:45:52 | [diff] [blame] | 62 | REMOTE_SSH_FLAGS=" -o StrictHostKeyChecking=no -o CheckHostIP=no\ |
| 63 | -o BatchMode=yes" |
Caroline Tice | 3250e19 | 2011-09-19 23:33:46 | [diff] [blame] | 64 | |
Ahmad Sharif | cf1615e | 2011-11-15 21:53:01 | [diff] [blame] | 65 | run_remote_command () |
| 66 | { |
| 67 | ssh -i ${TMP_DIR}/testing_rsa \ |
| 68 | ${REMOTE_SSH_FLAGS} root@${FLAGS_remote} ${VM_PORT} \ |
| 69 | "$@" |
| 70 | } |
| 71 | |
Caroline Tice | 3250e19 | 2011-09-19 23:33:46 | [diff] [blame] | 72 | ssh_to_remote_machine () |
| 73 | { |
| 74 | local command=$1 |
| 75 | local error_msg=$2 |
| 76 | |
Ahmad Sharif | cf1615e | 2011-11-15 21:53:01 | [diff] [blame] | 77 | if ! run_remote_command "${command}" ; then |
Caroline Tice | 3250e19 | 2011-09-19 23:33:46 | [diff] [blame] | 78 | die "${error_msg}" |
| 79 | fi |
| 80 | } |
| 81 | |
| 82 | validate_command_options () |
| 83 | { |
| 84 | # Verify we have at least a board, toolchain and remote file. |
| 85 | |
| 86 | if [[ -z "${BOARD}" ]] ; then |
| 87 | die "--board is required." |
| 88 | fi |
| 89 | |
| 90 | if [[ -z "${CHOST}" ]] ; then |
| 91 | die "Unable to determine correct toolchain from board." |
| 92 | fi |
| 93 | |
Ahmad Sharif | cf1615e | 2011-11-15 21:53:01 | [diff] [blame] | 94 | if [[ -z "${FLAGS_remote_pid}" ]] ; then |
| 95 | if [[ -z "${FLAGS_remote_file}" ]] ; then |
Ken Mixter | 1853cc2 | 2011-11-19 02:20:27 | [diff] [blame] | 96 | if [[ -z "${FLAGS_attach}" ]] ; then |
| 97 | die "--remote_file is required." |
| 98 | fi |
Ahmad Sharif | cf1615e | 2011-11-15 21:53:01 | [diff] [blame] | 99 | fi |
Caroline Tice | 3250e19 | 2011-09-19 23:33:46 | [diff] [blame] | 100 | fi |
| 101 | |
| 102 | # Verify that the correct cross-gdb has been built first! |
| 103 | |
| 104 | if [[ ! -f /usr/bin/${CHOST}-gdb ]] ; then |
| 105 | die "${CHOST}-gdb does not exist. Please run setup_board." |
| 106 | fi |
| 107 | |
| 108 | # Verify that the IP Address is currently active. |
| 109 | |
Caroline Tice | 6dc7201 | 2011-10-20 17:23:50 | [diff] [blame] | 110 | if [[ -z "${FLAGS_remote}" ]] ; then |
Caroline Tice | 3250e19 | 2011-09-19 23:33:46 | [diff] [blame] | 111 | die "No IP address specified." |
| 112 | fi |
| 113 | |
Caroline Tice | 6dc7201 | 2011-10-20 17:23:50 | [diff] [blame] | 114 | echo "Verifying IP address ${FLAGS_remote} (this will take a few\ |
Caroline Tice | 3250e19 | 2011-09-19 23:33:46 | [diff] [blame] | 115 | seconds)..." |
| 116 | |
Caroline Tice | 6dc7201 | 2011-10-20 17:23:50 | [diff] [blame] | 117 | if ! ping -c 3 -q ${FLAGS_remote} > /dev/null ; then |
| 118 | die "${FLAGS_remote} is not currently available." |
Caroline Tice | 3250e19 | 2011-09-19 23:33:46 | [diff] [blame] | 119 | fi |
| 120 | |
Ken Mixter | 1853cc2 | 2011-11-19 02:20:27 | [diff] [blame] | 121 | if [[ -n "${FLAGS_attach}" ]]; then |
| 122 | if [[ "${FLAGS_attach}" == "browser" ]]; then |
| 123 | FLAGS_remote_pid=$(run_remote_command \ |
| 124 | "pstree -p|grep session_manager|cut -d\( -f3 | cut -d\) -f1") |
| 125 | if [ -z "${FLAGS_remote_pid}" ]; then |
| 126 | die "Unable to find browser process" |
| 127 | fi |
| 128 | else |
| 129 | FLAGS_remote_pid=$(run_remote_command "pgrep -f '${FLAGS_attach}'") |
| 130 | local count=$(echo ${FLAGS_remote_pid} | wc -w) |
| 131 | if [ ${count} -eq 0 ]; then |
| 132 | die "No process matching ${FLAGS_attach}" |
| 133 | elif [ ${count} -gt 1 ]; then |
| 134 | error "Multiple (${count}) processes matching \"${FLAGS_attach}\":" |
| 135 | local pids=$(echo "${FLAGS_remote_pid}" | tr '\n' ' ') |
| 136 | run_remote_command "ps ${pids}" |
| 137 | exit 1 |
| 138 | fi |
| 139 | fi |
| 140 | fi |
| 141 | |
Ahmad Sharif | cf1615e | 2011-11-15 21:53:01 | [diff] [blame] | 142 | if [[ ${FLAGS_remote_pid} -ne 0 ]] ; then |
| 143 | local ssh_cmd="readlink -e /proc/${FLAGS_remote_pid}/exe" |
| 144 | local err_msg="${FLAGS_remote_pid} is not a valid PID on\ |
| 145 | ${FLAGS_remote}" |
| 146 | FLAGS_remote_file=$(run_remote_command "${ssh_cmd}") |
| 147 | if [[ $? -ne 0 ]] ; then |
| 148 | die "${err_msg}" |
| 149 | fi |
| 150 | fi |
| 151 | |
| 152 | if [[ ! -z "${FLAGS_remote_file}" ]] ; then |
| 153 | if [[ ${FLAGS_remote_file:0:1} != '/' ]] ; then |
| 154 | die "--remote_file must contain full pathname." |
| 155 | fi |
| 156 | fi |
| 157 | |
Caroline Tice | 3250e19 | 2011-09-19 23:33:46 | [diff] [blame] | 158 | # Verify that the debug version of the remote file exists. |
| 159 | |
| 160 | if [ ! -x "${BOARD_ROOT}${FLAGS_remote_file}" ]; then |
| 161 | echo |
| 162 | warn "${BOARD_ROOT}${FLAGS_remote_file} does not exist on your local" |
| 163 | warn "machine or is not executable. You may need to re-run build_packages" |
| 164 | warn "before attempting to debug." |
| 165 | echo |
| 166 | read -p "Do you want to stop now? [y/n] " y_or_n |
| 167 | case "$y_or_n" in |
| 168 | y | Y ) exit 1 ;; |
| 169 | *) ;; |
| 170 | esac |
| 171 | fi |
Caroline Tice | 3250e19 | 2011-09-19 23:33:46 | [diff] [blame] | 172 | } |
| 173 | |
| 174 | setup_remote_iptable () |
| 175 | { |
| 176 | # Update the iptables on the remote device |
| 177 | |
| 178 | local ssh_cmd="/sbin/iptables -A INPUT -p tcp --dport ${FLAGS_port}\ |
| 179 | -j ACCEPT" |
| 180 | local err_msg="Unable to add port to iptables." |
| 181 | ssh_to_remote_machine "${ssh_cmd}" "${err_msg}" |
| 182 | } |
| 183 | |
| 184 | start_remote_gdbserver () |
| 185 | { |
| 186 | # Start gdbserver on the remote device |
| 187 | |
| 188 | local gdbserver_cmd="gdbserver :${FLAGS_port} ${FLAGS_remote_file}" |
| 189 | if [[ ${FLAGS_remote_pid} -ne 0 ]] ; then |
| 190 | gdbserver_cmd="gdbserver --attach :${FLAGS_port} ${FLAGS_remote_pid}" |
| 191 | fi |
| 192 | |
| 193 | echo "Starting up gdbserver on your remote device." |
| 194 | local ssh_cmd="nohup ${gdbserver_cmd} > /tmp/gdbserver.out 2>&1 &" |
Caroline Tice | 6dc7201 | 2011-10-20 17:23:50 | [diff] [blame] | 195 | local err_msg="Unable to ssh into root@${FLAGS_remote}." |
Caroline Tice | 3250e19 | 2011-09-19 23:33:46 | [diff] [blame] | 196 | ssh_to_remote_machine "${ssh_cmd}" "${err_msg}" |
| 197 | } |
| 198 | |
| 199 | generate_gdbinit_file () |
| 200 | { |
| 201 | # Create board-and-notebook-specific .gdbinit file. |
| 202 | |
Ahmad Sharif | cf1615e | 2011-11-15 21:53:01 | [diff] [blame] | 203 | cat <<-EOF > ${GDBINIT_FILE} |
Caroline Tice | 3250e19 | 2011-09-19 23:33:46 | [diff] [blame] | 204 | |
| 205 | define remote_connect |
| 206 | set \$file="${FLAGS_remote_file}" |
| 207 | python import os |
| 208 | python filename = str (gdb.parse_and_eval ("\$file")) |
| 209 | python fullname = os.path.join ("${BOARD_ROOT}", filename) |
| 210 | python file_command = "file " + fullname |
| 211 | python gdb.execute (file_command) |
Caroline Tice | 6dc7201 | 2011-10-20 17:23:50 | [diff] [blame] | 212 | python remote_ip_address = "${FLAGS_remote}" |
Caroline Tice | 3250e19 | 2011-09-19 23:33:46 | [diff] [blame] | 213 | python remote_port = "${FLAGS_port}" |
| 214 | python remote_cmd = "target remote " + remote_ip_address + ":" + remote_port |
| 215 | python gdb.execute (remote_cmd) |
| 216 | end |
| 217 | |
| 218 | set sysroot $BOARD_ROOT |
| 219 | set debug-file-directory $BOARD_ROOT/usr/lib/debug |
Ahmad Sharif | cf1615e | 2011-11-15 21:53:01 | [diff] [blame] | 220 | remote_connect |
Caroline Tice | 3250e19 | 2011-09-19 23:33:46 | [diff] [blame] | 221 | EOF |
| 222 | } |
| 223 | |
Caroline Tice | cce25bd | 2011-10-07 22:45:52 | [diff] [blame] | 224 | |
| 225 | # Some special set up is required for accessing the VM on a local machine... |
| 226 | |
| 227 | VM_PORT="" |
| 228 | PORT_FORWARDING="" |
| 229 | |
Caroline Tice | 6dc7201 | 2011-10-20 17:23:50 | [diff] [blame] | 230 | if [[ "${FLAGS_remote}" == "localhost" || |
| 231 | "${FLAGS_remote}" == "127.0.0.1" ]] ; then |
Caroline Tice | cce25bd | 2011-10-07 22:45:52 | [diff] [blame] | 232 | VM_PORT=" -p 9222" |
| 233 | PORT_FORWARDING=" -L ${FLAGS_port}:localhost:${FLAGS_port}" |
| 234 | else |
| 235 | setup_remote_iptable |
| 236 | fi |
| 237 | |
Caroline Tice | 3250e19 | 2011-09-19 23:33:46 | [diff] [blame] | 238 | validate_command_options |
Caroline Tice | cce25bd | 2011-10-07 22:45:52 | [diff] [blame] | 239 | |
| 240 | # If accessing the VM on the local machine, need a second ssh session open, |
| 241 | # for port forwarding, so gdb can find gdbserver... |
| 242 | |
| 243 | SSHD_PID=0 |
| 244 | if [[ -n "${VM_PORT}" ]] ; then |
| 245 | # Call ssh directly rather than using 'ssh_to_remote_machine' because |
| 246 | # too many things about this particular call are different. |
| 247 | ssh -i ${TMP_DIR}/testing_rsa -N \ |
| 248 | ${REMOTE_SSH_FLAGS} \ |
Caroline Tice | 6dc7201 | 2011-10-20 17:23:50 | [diff] [blame] | 249 | root@${FLAGS_remote} ${VM_PORT} ${PORT_FORWARDING} & |
Caroline Tice | cce25bd | 2011-10-07 22:45:52 | [diff] [blame] | 250 | SSH_PID=$! |
| 251 | fi |
| 252 | |
Caroline Tice | 3250e19 | 2011-09-19 23:33:46 | [diff] [blame] | 253 | start_remote_gdbserver |
| 254 | |
| 255 | echo "gdbserver is now running remotely. Output will be written to " |
| 256 | echo "/tmp/gdbserver.out on your remote device." |
| 257 | |
| 258 | generate_gdbinit_file |
| 259 | |
Ken Mixter | 1853cc2 | 2011-11-19 02:20:27 | [diff] [blame] | 260 | echo "Some helpful GDB commands:" |
| 261 | echo "directory <path> -- causes path to be searched for source files." |
| 262 | echo "info functions <regexp> -- find function matching given regexp." |
Caroline Tice | 3250e19 | 2011-09-19 23:33:46 | [diff] [blame] | 263 | echo |
Ken Mixter | 1853cc2 | 2011-11-19 02:20:27 | [diff] [blame] | 264 | echo "Some helpful gdb_remote specific commands:" |
| 265 | echo "remote_connect -- reestablish remote connection." |
Caroline Tice | 3250e19 | 2011-09-19 23:33:46 | [diff] [blame] | 266 | echo |
| 267 | |
| 268 | # Start gdb on local machine. |
| 269 | |
Caroline Tice | cce25bd | 2011-10-07 22:45:52 | [diff] [blame] | 270 | ${CHOST}-gdb |
| 271 | |
| 272 | cleanup |