Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bd0e8af7 authored by Dmitriy Ivanov's avatar Dmitriy Ivanov Committed by Gerrit Code Review
Browse files

Merge "Replacement for gdbclient"

parents 36084e64 9b8e4b37
Loading
Loading
Loading
Loading
+142 −1
Original line number Diff line number Diff line
@@ -963,10 +963,151 @@ function is64bit()
    fi
}

function adb_get_product_device() {
  echo `adb shell getprop ro.product.device | sed s/.$//`
}

# returns 0 when process is not traced
function adb_get_traced_by() {
  echo `adb shell cat /proc/$1/status | grep -e "^TracerPid:" | sed "s/^TracerPid:\t//" | sed s/.$//`
}

function gdbclient() {
  # TODO:
  # 1. Check for ANDROID_SERIAL/multiple devices
  local PROCESS_NAME="n/a"
  local PID=$1
  local PORT=5039
  if [ -z "$PID" ]; then
    echo "Usage: gdbclient <pid|processname> [port number]"
    return -1
  fi
  local DEVICE=$(adb_get_product_device)

  if [ -z "$DEVICE" ]; then
    echo "Error: Unable to get device name. Please check if device is connected and ANDROID_SERIAL is set."
    return -2
  fi

  if [ -n "$2" ]; then
    PORT=$2
  fi

  local ROOT=$(gettop)
  if [ -z "$ROOT" ]; then
    # This is for the situation with downloaded symbols (from the build server)
    # we check if they are available.
    ROOT=`realpath .`
  fi

  local OUT_ROOT="$ROOT/out/target/product/$DEVICE"
  local SYMBOLS_DIR="$OUT_ROOT/symbols"

  if [ ! -d $SYMBOLS_DIR ]; then
    echo "Error: couldn't find symbols: $SYMBOLS_DIR does not exist or is not a directory."
    return -3
  fi

  # let's figure out which executable we are about to debug

  # check if user specified a name -> resolve to pid
  if [[ ! "$PID" =~ ^[0-9]+$ ]] ; then
    PROCESS_NAME=$PID
    PID=$(pid --exact $PROCESS_NAME)
    if [ -z "$PID" ]; then
      echo "Error: couldn't resolve pid by process name: $PROCESS_NAME"
      return -4
    fi
  fi

  local EXE=`adb shell readlink /proc/$PID/exe | sed s/.$//`
  # TODO: print error in case there is no such pid
  local LOCAL_EXE_PATH=$SYMBOLS_DIR$EXE

  if [ ! -f $LOCAL_EXE_PATH ]; then
    echo "Error: unable to find symbols for executable $EXE: file $LOCAL_EXE_PATH does not exist"
    return -5
  fi

  local USE64BIT=""

  if [[ "$(file $LOCAL_EXE_PATH)" =~ 64-bit ]]; then
    USE64BIT="64"
  fi

  local GDB=
  local GDB64=
  local CPU_ABI=`adb shell getprop ro.product.cpu.abilist | sed s/.$//`
  # TODO: we assume these are available via $PATH
  if [[ $CPU_ABI =~ (^|,)arm64 ]]; then
    GDB=arm-linux-androideabi-gdb
    GDB64=aarch64-linux-android-gdb
  elif [[ $CPU_ABI =~ (^|,)arm ]]; then
    GDB=arm-linux-androideabi-gdb
  elif [[ $CPU_ABI =~ (^|,)x86_64 ]]; then
    GDB=x86_64-linux-androideabi-gdb
  elif [[ $CPU_ABI =~ (^|,)x86 ]]; then
    GDB=x86_64-linux-androideabi-gdb
  elif [[ $CPU_ABI =~ (^|,)mips64 ]]; then
    GDB=mipsel-linux-android-gdb
    GDB64=mips64el-linux-android-gdb
  elif [[ $CPU_ABI =~ (^|,)mips ]]; then
    GDB=mipsel-linux-android-gdb
  else
    echo "Error: unrecognized cpu.abilist: $CPU_ABI"
    return -6
  fi

  # TODO: check if tracing process is gdbserver and not some random strace...
  if [ $(adb_get_traced_by $PID) -eq 0 ]; then
    # start gdbserver
    echo "Starting gdbserver..."
    # TODO: check if adb is already listening $PORT
    # to avoid unnecessary calls
    echo ". adb forward for port=$PORT..."
    adb forward tcp:$PORT tcp:$PORT
    echo ". starting gdbserver to attach to pid=$PID..."
    adb shell gdbserver$USE64BIT :$PORT --attach $PID &
    echo ". give it couple of seconds to start..."
    sleep 2
    echo ". done"
  else
    echo "It looks like gdbserver is already attached to $PID (process is traced), trying to connect to it using local port=$PORT"
  fi

  local OUT_SO_SYMBOLS=$SYMBOLS_DIR/system/lib$USE64BIT
  local OUT_VENDOR_SO_SYMBOLS=$SYMBOLS_DIR/vendor/lib$USE64BIT
  local ART_CMD=""

  echo >|"$OUT_ROOT/gdbclient.cmds" "set solib-absolute-prefix $SYMBOLS_DIR"
  echo >>"$OUT_ROOT/gdbclient.cmds" "set solib-search-path $OUT_SO_SYMBOLS:$OUT_SO_SYMBOLS/hw:$OUT_SO_SYMBOLS/ssl/engines:$OUT_SO_SYMBOLS/drm:$OUT_SO_SYMBOLS/egl:$OUT_SO_SYMBOLS/soundfx:$OUT_VENDOR_SO_SYMBOLS:$OUT_VENDOR_SO_SYMBOLS/hw:$OUT_VENDOR_SO_SYMBOLS/egl"
  local DALVIK_GDB_SCRIPT=$ROOT/development/scripts/gdb/dalvik.gdb
  if [ -f $DALVIK_GDB_SCRIPT ]; then
    echo >>"$OUT_ROOT/gdbclient.cmds" "source $DALVIK_GDB_SCRIPT"
    ART_CMD="art-on"
  else
    echo "Warning: couldn't find $DALVIK_GDB_SCRIPT - ART debugging options will not be available"
  fi
  echo >>"$OUT_ROOT/gdbclient.cmds" "target remote :$PORT"
  if [[ $EXE =~ (^|/)(app_process|dalvikvm)(|32|64)$ ]]; then
    echo >> "$OUT_ROOT/gdbclient.cmds" $ART_CMD
  fi

  echo >>"$OUT_ROOT/gdbclient.cmds" ""

  local WHICH_GDB=$GDB

  if [ -n "$USE64BIT" -a -n "$GDB64" ]; then
    WHICH_GDB=$GDB64
  fi

  gdbwrapper $WHICH_GDB "$OUT_ROOT/gdbclient.cmds" "$LOCAL_EXE_PATH"
}

# gdbclient now determines whether the user wants to debug a 32-bit or 64-bit
# executable, set up the approriate gdbserver, then invokes the proper host
# gdb.
function gdbclient()
function gdbclient_old()
{
   local OUT_ROOT=$(get_abs_build_var PRODUCT_OUT)
   local OUT_SYMBOLS=$(get_abs_build_var TARGET_OUT_UNSTRIPPED)