From 8e0dd347536b4e3aaf0233627fa269bf0f96bf36 Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Fri, 20 Mar 2020 00:10:11 +0100 Subject: [PATCH] Improve RetroShare Android tools and documentation --- build_scripts/Android/README.asciidoc | 149 ++- build_scripts/Android/README.html | 996 ++++++++++++++++++ .../Android/generate_gdb_init_commands.sh | 85 ++ .../Android/prepare-toolchain-clang.sh | 2 +- build_scripts/Android/pull_sysroot.sh | 90 ++ build_scripts/Android/start_gdbserver.sh | 101 ++ 6 files changed, 1419 insertions(+), 4 deletions(-) create mode 100644 build_scripts/Android/README.html create mode 100755 build_scripts/Android/generate_gdb_init_commands.sh create mode 100755 build_scripts/Android/pull_sysroot.sh create mode 100755 build_scripts/Android/start_gdbserver.sh diff --git a/build_scripts/Android/README.asciidoc b/build_scripts/Android/README.asciidoc index d045281b9..474d2f3ee 100644 --- a/build_scripts/Android/README.asciidoc +++ b/build_scripts/Android/README.asciidoc @@ -1,8 +1,8 @@ += RetroShare development on Android + // SPDX-FileCopyrightText: RetroShare Team // SPDX-License-Identifier: CC-BY-SA-4.0 -Compile Retroshare for Android -============================== Compiling an application for Android is not as easy as one would imagine, expecially one like RetroShare that has a big codebase and is not well @@ -179,7 +179,130 @@ Opening RetroShare android app now should show your old profile. == Debugging with GDB -QtCreator actually support debugging only for the foreground activity, so to +If building RetroShare Android package seems tricky, setting up a functional +debugging environement for it feels like black magic. This section is meant to +help you doing it with less headache and hopefully in a reproducible way. + +Unfortunately at the time of the last update to this guide, Qt build system +strips debugging symbols from the package and from the buildroot also if you +compile with debugging enabled. Fiddling with `qmake` configurations and +variables like `CONFIG+=debug`, `CONFIG+=force_debug_info` or `QMAKE_STRIP` +either as commandline arguments or inside retroshare `.pro` and `.pri` files is +uneffective. IMHO Qt should handle this on itself so it is probably worth +reporting a bug to them. So to workaround this problem you need to fiddle a bit +with the Android NDK. In my case I always keep +Debug+ or +Release+ suffix in +my build directory name depending on what kind of build it is, so I use this +information and modify `llvm-strip` in a way that it will strip only if stripped +file path doesn't contain +Debug+. + +.Modify llvm-strip inside Android NDK +-------------------------------------------------------------------------------- +## Set ANDROID_NDK_PATH to your Android NDK installation path +export ANDROID_NDK_PATH="/opt/android-ndk/" + +## Define a convenience variable with llvm-strip path +export ANDROID_NDK_LLVM_STRIP="${ANDROID_NDK_PATH}/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-strip" + +## If not existing yer create a backup of the original llvm-strip +[ -f "${ANDROID_NDK_LLVM_STRIP}.back" ] || + cp "${ANDROID_NDK_LLVM_STRIP}" "${ANDROID_NDK_LLVM_STRIP}.back" + +## Create a new llvm-strip that does nothing if the argument path contains Debug +cat > "${ANDROID_NDK_LLVM_STRIP}" << LLVMSTRIPTRICK +#!/bin/bash + +echo "\${2}" | grep -q Debug || + "${ANDROID_NDK_LLVM_STRIP}.back" --strip-all "\${2}" + +LLVMSTRIPTRICK + +## Eventually you can revert back simply by running +# `mv "${ANDROID_NDK_LLVM_STRIP}.back" "${ANDROID_NDK_LLVM_STRIP}"` +-------------------------------------------------------------------------------- + + +To attach to the `retroshare-service` running on Android you need also to pull a +debugging sysroot out of your device first, RetroShare sources provides an +helper script to do that. + +.Prepare debugging sysroot with helper script +[source,bash] +-------------------------------------------------------------------------------- +## Set RetroShare source path +export RS_SOURCE_DIR="${HOME}/Development/rs-develop" + +## Optionally set your device ID first available will be used, you can run +## `adb devices` to list available devices. +#export ANDROID_SERIAL="YT013PSPGK" + +## Optionally set a path where to save the debugging sysroot otherwise default +## is used. +#export DEBUG_SYSROOT="${HOME}/Builds/debug_sysroot/${ANDROID_SERIAL}/" + +## Run the helper script +${RS_SOURCE_DIR}/build_scripts/Android/pull_sysroot.sh +-------------------------------------------------------------------------------- + +.Prepare Android NDK GDB configurations +[source,bash] +-------------------------------------------------------------------------------- +## Optionally set Qt version variable consistently with your installation +export QT_VERSION="5.12.4" + +## Optionally set Qt architecture variable consistently with Android device +export QT_ARCH="arm64_v8a" + +## Optionally set Qt path variable consistently with your installation +export QT_DIR="/opt/Qt-${QT_VERSION}/${QT_VERSION}/" + +## Optionally set RetroShare buildroot path +export RS_BUILD_DIR="${HOME}/Builds/RetroShare-Android_for_${QT_ARCH}_Clang_Qt_${QT_VERSION//./_}_android_${QT_ARCH}-Debug/" + +## Optionally set gdb config file path +export GDB_CONFIGS_FILE="${HOME}/Builds/gdb_configs_${QT_ARCH}" + +## Generate Android NDK GDB configuration +${RS_SOURCE_DIR}/build_scripts/Android/generate_gdb_init_commands.sh +-------------------------------------------------------------------------------- + + +You will need to run the following steps everytime you want to debug +`retroshare-service` on Android. + +Make sure `retroshare-service` is running on your connected Android device. + +.Run GDB server on your Android device from your host console +[source,bash] +-------------------------------------------------------------------------------- +${RS_SOURCE_DIR}/build_scripts/Android/start_gdbserver.sh +-------------------------------------------------------------------------------- + + +.Run Android NDK GDB on your workstation and attach +[source,bash] +-------------------------------------------------------------------------------- +## Start NDK gdb +${ANDROID_NDK_PATH}/prebuilt/linux-x86_64/bin/gdb + +## Instruct GDB how and where to find debugging symbols +(gdb) source $GDB_CONFIGS_FILE + +## Connect to the gdbserver running on the phone +(gdb) target remote 127.0.01:5039 + +## Have fun debugging +(gdb) +-------------------------------------------------------------------------------- + + +== Debugging with Qt Creator + +WARNING: As of the last update to this guide, debugging retroshare-service +running on Android via Qt creator doesn't wrok even with all the trickery +explained in this section, you better learn how to debug with GDB reading +carefully previous section. + +Qt Creator actually support debugging only for the foreground activity, so to debug what's happening in the core extra trickery is needed. - Run the App in Debug mode from QtCreator "Start Debugging" button @@ -239,6 +362,17 @@ TIP: Some time WiFi power saving on Android mess with the GDB connection, to prevent that from appening open another +adb shell+ and live +ping+ toward your work-station running +== Embedding into other Android packages + +As showed by https://elrepo.io/[elRepo.io] developers it is possible and quite +easy to embed `retroshare-service` into other Android packages see description + +https://gitlab.com/elRepo.io/elRepo.io-android/-/blob/master/README.adoc + +And implementation details + +https://gitlab.com/elRepo.io/elRepo.io-android/-/blob/master/android/app/build.gradle + == Furter Readings @@ -254,3 +388,12 @@ your work-station running - link:https://fw4spl-org.github.io/fw4spl-blog/2015/07/27/Native-debugging-on-Android-with-QtCreator.html[] - link:https://fragglet.livejournal.com/19646.html[] - link:https://github.com/android-ndk/ndk/issues/773[How to build without using standalone toolchain?] + +== License + +Copyright (C) 2016-2020 Gioacchino Mazzurco + +Copyright (C) 2020 Asociación Civil Altermundi + + +This work is licensed under a Creative Commons Attribution-Share Alike 4.0 International License. + +image::https://i.creativecommons.org/l/by-sa/4.0/88x31.png[Creative Commons License, link=http://creativecommons.org/licenses/by-sa/4.0/] diff --git a/build_scripts/Android/README.html b/build_scripts/Android/README.html new file mode 100644 index 000000000..d73413834 --- /dev/null +++ b/build_scripts/Android/README.html @@ -0,0 +1,996 @@ + + + + + + + +Compile Retroshare for Android + + + + + +
+
+
+
+

Compiling an application for Android is not as easy as one would imagine, +expecially one like RetroShare that has a big codebase and is not well +documented. This document is aimed to empower the reader so she can hopefully +succed or at least have a significant help in compiling her own RetroShare APK +installable on Android.

+
+
+
+
+

Preparing The Environement

+
+
+

First of all setup your Qt for Android development environement following the +guide on the Qt for android web site. +At this point you should have Android SDK, Android NDK, and Qt for Android +working fine, and you should be capable of executing on an Android emulator or +on your Android phone Qt for Android examples.

+
+
+

But RetroShare is not as simple to compile as those examples. The good news is +that Android NDK ships all the necessary to build a custom toolchain that is +suitable to build RetroShare. +In order to build the toolchain with needed libraries RetroShare provides the +android-prepare-toolchain.sh script; before you execute it you should define +some variables the script cannot determine in an easy and reliable manner by +itself in your terminal.

+
+
+
+
## The path where Android NDK is installed in your system
+export ANDROID_NDK_PATH="/opt/android-ndk/"
+
+## The path where your fresh compiled toolchain will be installed, make sure
+## the parent exists
+export NATIVE_LIBS_TOOLCHAIN_PATH="${HOME}/Builds/android-toolchains/retroshare-android/"
+
+## The CPU architecture of the Android device you want to target
+export ANDROID_NDK_ARCH="arm"
+
+## The Android API level the Android device you want to target
+export ANDROID_PLATFORM_VER="16"
+
+## The number of core that yout host CPU have (just to speed up compilation) set
+## it to 1 if unsure
+export HOST_NUM_CPU=1
+
+./android-prepare-toolchain.sh
+
+
+
+
+
+

Preparing Qt Creator

+
+
+

Now that your environement is set up you should configure Qt Creator for Android +following the +official guide. +At the end of this step your Qt Creator should recognize the Android compiler +and the Qt for Android kit.

+
+
+

Your Kit is now ready to use. Now you can open RetroShare as a Qt Creator +project and in the Projects left menu add the newly created kit if not already +present, so you can select it on the build type selection button down on the +left.

+
+
+

Now you need to set properly a few options like JSONAPI_GENERATOR_EXE and +disable some of RetroShare modules like retroshare-gui that are not available +on Android so you will have to go to

+
+
+

Qt Creator left pane → Projects → Build and Run → Android SOMESTUFF kit → +Build Steps → qmake → Additional arguments

+
+
+

and add the following configurations (change Your_Path according to your +deployment)

+
+
+
+
CONFIG+=retroshare_service CONFIG+=rs_jsonapi CONFIG+=rs_deep_search
+RS_UPNP_LIB=miniupnpc
+JSONAPI_GENERATOR_EXE=Your_Path/jsonapi-generator/src/jsonapi-generator
+NATIVE_LIBS_TOOLCHAIN_PATH=Your_Path/retroshare-android-16-arm/
+CONFIG+=no_retroshare_gui CONFIG+=no_rs_service_webui_terminal_password
+CONFIG+=no_rs_service_terminal_login
+
+
+
+ + + + + +
+
Tip
+
+Some versions of QtCreator try to find the Android SDK in +/opt/android/sdk. A workaround to this is to make a symbolic link there +pointing to your SDK installation path, like +mkdir -p /opt/android/sdk && ln -s /home/user/android-sdk-linux +/opt/android/sdk +
+
+
+
+
+

Quircks

+
+
+

Protected Apps

+
+

On some Android devices like Huawei ALE-L21 background applications are +killed when screen is turned off unless they are in the protected app list. +At moment seems apps developers don’t have a way to have the application +protected by default, unless the phone vendor decide the app is popular so +the user have to enable protection for RetroShare manually on those mobile +phones.

+
+
+


+To enable enable protection: Android menu → Settings → Privacy & security +→ Protected apps → RetroShare
+

+
+
+

Other devices may offer similar features please report them.

+
+
+
+

APK signature mismatch

+
+

If you try to install a RetroShare APK that comes from a different source +(eg: if you try to upgrade from F-Droid when you originally installed an APK +build by yourself) Android will prevent that from happening. In that case the +only solution is to uninstall the app and then install the new APK but if you do +it also the application data and your precious cryptographic keys, friend list +etc. will be lost forever. +To avoid that you can attempt to manually backup and then restore from the +command-line (adb backup seems not working either) to change the app source +without erasing the appliation data.

+
+
+ + + + + +
+
Caution
+
+Following steps require root access on your Android device +
+
+
+
Backup RetroShare Android application data
+
+
export ORIG_DIR="/data/data/org.retroshare.android.qml_app"
+export BACKUP_DIR="org.retroshare.android.qml_app.backup"
+
+adb root
+
+adb shell am force-stop org.retroshare.android.qml_app
+sleep 1s
+
+mkdir ${BACKUP_DIR}
+
+# Avoid adb pull failing
+adb shell rm ${ORIG_DIR}/files/.retroshare/libresapi.sock
+adb pull ${ORIG_DIR}/files/ ${BACKUP_DIR}/files/
+
+
+
+

After this you should be able to uninstall the old APK with your preferred +method, as example from the command-line.

+
+
+
Uninstall RetroShare Android from the command-line
+
+
adb uninstall org.retroshare.android.qml_app
+
+
+
+

Now you can install a different signature APK and then restore the application +data with the following commands.

+
+
+
+
export ORIG_DIR="/data/data/org.retroshare.android.qml_app"
+export BACKUP_DIR="org.retroshare.android.qml_app.backup"
+
+adb root
+
+## Launch the app to make sure the parent directory exists and has proper owner
+adb shell monkey -p org.retroshare.android.qml_app -c android.intent.category.LAUNCHER 1
+sleep 1s
+
+adb shell am force-stop org.retroshare.android.qml_app
+sleep 1s
+
+
+APP_OWNER="$(adb shell busybox ls -lnd ${ORIG_DIR} | awk '{print $3":"$4}')"
+adb shell rm -rf ${ORIG_DIR}/files
+adb push ${BACKUP_DIR}/files/ ${ORIG_DIR}/files/
+adb shell busybox chown -R ${APP_OWNER} ${ORIG_DIR}/files/
+
+
+
+

Opening RetroShare android app now should show your old profile.

+
+
+
+
+
+

Debugging with GDB

+
+
+

If building RetroShare Android package seems tricky, setting up a functional +debugging environement for it feels like black magic. This section is meant to +help you doing it with less headache and hopefully in a reproducible way.

+
+
+

Unfortunately at the time of the last update to this guide, Qt build system +strips debugging symbols from the package and from the buildroot also if you +compile with debugging enabled. Fiddling with qmake configurations and +variables like CONFIG+=debug, CONFIG+=force_debug_info or QMAKE_STRIP +either as commandline arguments or inside retroshare .pro and .pri files is +uneffective. IMHO Qt should handle this on itself so it is probably worth +reporting a bug to them. So to workaround this problem you need to fiddle a bit +with the Android NDK. In my case I always keep Debug or Release suffix in +my build directory name depending on what kind of build it is, so I use this +information and modify llvm-strip in a way that it will strip only if stripped +file path doesn’t contain Debug.

+
+
+
Modify llvm-strip inside Android NDK
+
+
## Set ANDROID_NDK_PATH to your Android NDK installation path
+export ANDROID_NDK_PATH="/opt/android-ndk/"
+
+## Define a convenience variable with llvm-strip path
+export ANDROID_NDK_LLVM_STRIP="${ANDROID_NDK_PATH}/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-strip"
+
+## If not existing yer create a backup of the original llvm-strip
+[ -f "${ANDROID_NDK_LLVM_STRIP}.back" ] ||
+	cp "${ANDROID_NDK_LLVM_STRIP}" "${ANDROID_NDK_LLVM_STRIP}.back"
+
+## Create a new llvm-strip that does nothing if the argument path contains Debug
+cat > "${ANDROID_NDK_LLVM_STRIP}" << LLVMSTRIPTRICK
+#!/bin/bash
+
+echo "\${2}" | grep -q Debug ||
+	"${ANDROID_NDK_LLVM_STRIP}.back" --strip-all "\${2}"
+
+LLVMSTRIPTRICK
+
+## Eventually you can revert back simply by running
+# `mv "${ANDROID_NDK_LLVM_STRIP}.back" "${ANDROID_NDK_LLVM_STRIP}"`
+
+
+
+

To attach to the retroshare-service running on Android you need also to pull a +debugging sysroot out of your device first, RetroShare sources provides an +helper script to do that.

+
+
+
Prepare debugging sysroot with helper script
+
+
## Set RetroShare source path
+export RS_SOURCE_DIR="${HOME}/Development/rs-develop"
+
+## Optionally set your device ID first available will be used, you can run
+## `adb devices` to list available devices.
+#export ANDROID_SERIAL="YT013PSPGK"
+
+## Optionally set a path where to save the debugging sysroot otherwise default
+## is used.
+#export DEBUG_SYSROOT="${HOME}/Builds/debug_sysroot/${ANDROID_SERIAL}/"
+
+## Run the helper script
+${RS_SOURCE_DIR}/build_scripts/Android/pull_sysroot.sh
+
+
+
+
Prepare Android NDK GDB configurations
+
+
## Optionally set Qt version variable consistently with your installation
+export QT_VERSION="5.12.4"
+
+## Optionally set Qt architecture variable consistently with Android device
+export QT_ARCH="arm64_v8a"
+
+## Optionally set Qt path variable consistently with your installation
+export QT_DIR="/opt/Qt-${QT_VERSION}/${QT_VERSION}/"
+
+## Optionally set RetroShare buildroot path
+export RS_BUILD_DIR="${HOME}/Builds/RetroShare-Android_for_${QT_ARCH}_Clang_Qt_${QT_VERSION//./_}_android_${QT_ARCH}-Debug/"
+
+## Optionally set gdb config file path
+export GDB_CONFIGS_FILE="${HOME}/Builds/gdb_configs_${QT_ARCH}"
+
+## Generate Android NDK GDB configuration
+${RS_SOURCE_DIR}/build_scripts/Android/generate_gdb_init_commands.sh
+
+
+
+

You will need to run the following steps everytime you want to debug +retroshare-service on Android.

+
+
+

Make sure retroshare-service is running on your connected Android device.

+
+
+
Run GDB server on your Android device from your host console
+
+
${RS_SOURCE_DIR}/build_scripts/Android/start_gdbserver.sh
+
+
+
+
Run Android NDK GDB on your workstation and attach
+
+
## Start NDK gdb
+${ANDROID_NDK_PATH}/prebuilt/linux-x86_64/bin/gdb
+
+## Instruct GDB how and where to find debugging symbols
+(gdb) source $GDB_CONFIGS_FILE
+
+## Connect to the gdbserver running on the phone
+(gdb) target remote 127.0.01:5039
+
+## Have fun debugging
+(gdb)
+
+
+
+
+
+

Debugging with Qt Creator

+
+
+ + + + + +
+
Warning
+
+As of the last update to this guide, debugging retroshare-service +running on Android via Qt creator doesn’t wrok even with all the trickery +explained in this section, you better learn how to debug with GDB reading +carefully previous section. +
+
+
+

Qt Creator actually support debugging only for the foreground activity, so to +debug what’s happening in the core extra trickery is needed.

+
+
+
    +
  • +

    Run the App in Debug mode from QtCreator "Start Debugging" button

    +
  • +
  • +

    Enable QtCreator debugger console view Menu→Window→Debugger Log

    +
  • +
  • +

    Run show solib-search-path in the QtCreator GDB console

    +
  • +
  • +

    Take note of the output you get in the right pane of the console

    +
  • +
  • +

    Thanks https://stackoverflow.com/a/31164313 for the idea

    +
  • +
+
+
+ + + + + +
+
Tip
+
+QtCreator GDB console seems a bit buggy and easly trigger timeout +message when a command is run, in that case attempt to run the command while the +debugging is paused or at breakpoint, or with other similar tricks. +
+
+
+ + + + + +
+
Caution
+
+Following steps require root access on your Android device +
+
+
+

Now on your phone yuo need to authorize root access to applications, then once +you plug your sacrifical Android phone run this commands

+
+
+
Run gdbserver as root on Android phone
+
+
## Open a shell from your workstation on the connected Android phone
+adb shell
+
+## take the note of the phone IP address
+ip address show
+
+## Gain root permissions on the shell
+su
+
+## Attach with gdbserver and listen on one TCP port
+gdbserver :4567 --attach $(pgrep org.retroshare.android.qml_app:rs)
+
+
+
+
Prepare and run Android NDK GDB on your workstation
+
+
## Setup some convenience variables
+NDK_GDB="${ANDROID_NDK_PATH}/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gdb"
+RS_BUILD_PATH="${HOME}/Builds/RetroShare-Android_for_armeabi_v7a_GCC_4_9_Qt_5_9_2_android_armv7-Debug/"
+
+## Start Android NDK GDB of your phone architecture passing the executable
+$NDK_GDB $RS_BUILD_PATH/retroshare-android-service/src/libretroshare-android-service.so
+
+## Instruct GDB how and where to find debugging symbols
+(gdb) set auto-solib-add on
+(gdb) set solib-search-path THE:BIG:LIST:OF:DIRECTORIES:YOU:TAKE:NOTE:BEFORE
+
+## Connect to the gdbserver running on the phone
+(gdb) target remote $PHONE_IP:4567
+
+## Have fun debugging
+(gdb)
+
+
+
+ + + + + +
+
Tip
+
+Some time WiFi power saving on Android mess with the GDB connection, +to prevent that from appening open another adb shell and live ping toward +your work-station running +
+
+
+
+
+

Embedding into other Android packages

+
+
+

As showed by elRepo.io developers it is possible and quite +easy to embed retroshare-service into other Android packages see description

+
+ +
+

And implementation details

+
+ +
+
+ +
+

License

+
+
+

Copyright © 2016-2020 Gioacchino Mazzurco <gio@eigenlab.org>
+Copyright © 2020 Asociación Civil Altermundi <info@altermundi.net>

+
+
+

This work is licensed under a Creative Commons Attribution-Share Alike 4.0 International License.

+
+
+
+Creative Commons License +
+
+
+
+
+ + + \ No newline at end of file diff --git a/build_scripts/Android/generate_gdb_init_commands.sh b/build_scripts/Android/generate_gdb_init_commands.sh new file mode 100755 index 000000000..3a9883950 --- /dev/null +++ b/build_scripts/Android/generate_gdb_init_commands.sh @@ -0,0 +1,85 @@ +#!/bin/bash + +# Script to prepare Android NDK GDB configurations to debug retroshare-service +# +# Copyright (C) 2020 Gioacchino Mazzurco +# Copyright (C) 2020 Asociación Civil Altermundi +# +# This program is free software: you can redistribute it and/or modify it under +# the terms of the GNU Affero General Public License as published by the +# Free Software Foundation, version 3. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License along +# with this program. If not, see + + +## Define default value for variable, take two arguments, $1 variable name, +## $2 default variable value, if the variable is not already define define it +## with default value. +function define_default_value() +{ + VAR_NAME="${1}" + DEFAULT_VALUE="${2}" + + [ -z "${!VAR_NAME}" ] && export ${VAR_NAME}="${DEFAULT_VALUE}" +} + +define_default_value QT_VERSION "5.12.4" +define_default_value QT_ARCH "arm64_v8a" +define_default_value QT_DIR "/opt/Qt-${QT_VERSION}/${QT_VERSION}/" +define_default_value ANDROID_SERIAL "$(adb devices | head -n 2 | tail -n 1 | awk '{print $1}')" +define_default_value RS_BUILD_DIR "${HOME}/Builds/RetroShare-Android_for_${QT_ARCH}_Clang_Qt_${QT_VERSION//./_}_android_${QT_ARCH}-Debug/" +define_default_value RS_SOURCE_DIR "${HOME}/Development/rs-develop/" +define_default_value DEBUG_SYSROOT "${HOME}/Builds/debug_sysroot/${ANDROID_SERIAL}/" +define_default_value GDB_CONFIGS_FILE "${HOME}/Builds/gdb_configs_${QT_ARCH}" + +scanDir() +{ + find "$1" -type d -not -path '*/\.git/*' | tr '\n' ':' >> $GDB_CONFIGS_FILE +} + +putSeparator() +{ + echo >> $GDB_CONFIGS_FILE + echo >> $GDB_CONFIGS_FILE +} + +echo "set sysroot ${DEBUG_SYSROOT}" > $GDB_CONFIGS_FILE +putSeparator + +echo "set auto-solib-add on" >> $GDB_CONFIGS_FILE +echo -n "set solib-search-path " >> $GDB_CONFIGS_FILE +scanDir "${RS_BUILD_DIR}" +scanDir "${DEBUG_SYSROOT}" +scanDir "${QT_DIR}/android_${QT_ARCH}/lib/" +scanDir "${QT_DIR}/android_${QT_ARCH}/plugins/" +scanDir "${QT_DIR}/android_${QT_ARCH}/qml/" +putSeparator + +echo -n "directory " >> $GDB_CONFIGS_FILE +scanDir ${RS_SOURCE_DIR}/jsonapi-generator/src +scanDir ${RS_SOURCE_DIR}/libbitdht/src +scanDir ${RS_SOURCE_DIR}/openpgpsdk/src +scanDir ${RS_SOURCE_DIR}/libretroshare/src +scanDir ${RS_SOURCE_DIR}/retroshare-service/src +scanDir ${RS_SOURCE_DIR}/supportlibs/rapidjson/include/ +scanDir ${RS_SOURCE_DIR}/supportlibs/restbed/source/ +scanDir ${RS_SOURCE_DIR}/supportlibs/udp-discovery-cpp/ +scanDir ${RS_SOURCE_DIR}/supportlibs/restbed/dependency/asio/asio/include/ +scanDir ${RS_SOURCE_DIR}/supportlibs/restbed/dependency/catch/include/ +putSeparator + +## see https://stackoverflow.com/questions/28972367/gdb-backtrace-without-stopping +echo "catch signal SIGSEGV" >> $GDB_CONFIGS_FILE +echo "commands + bt + continue + end" >> $GDB_CONFIGS_FILE +putSeparator + +echo GDB_CONFIGS_FILE=$GDB_CONFIGS_FILE diff --git a/build_scripts/Android/prepare-toolchain-clang.sh b/build_scripts/Android/prepare-toolchain-clang.sh index 295f4604f..2c64a5186 100755 --- a/build_scripts/Android/prepare-toolchain-clang.sh +++ b/build_scripts/Android/prepare-toolchain-clang.sh @@ -2,7 +2,7 @@ # Script to prepare RetroShare Android package building toolchain # -# Copyright (C) 2016-2019 Gioacchino Mazzurco +# Copyright (C) 2016-2020 Gioacchino Mazzurco # # This program is free software: you can redistribute it and/or modify it under # the terms of the GNU Affero General Public License as published by the diff --git a/build_scripts/Android/pull_sysroot.sh b/build_scripts/Android/pull_sysroot.sh new file mode 100755 index 000000000..d474610e4 --- /dev/null +++ b/build_scripts/Android/pull_sysroot.sh @@ -0,0 +1,90 @@ +#!/bin/bash + +# Script to pull debugging sysroot from Android devices +# +# Copyright (C) 2020 Gioacchino Mazzurco +# Copyright (C) 2020 Asociación Civil Altermundi +# +# This program is free software: you can redistribute it and/or modify it under +# the terms of the GNU Affero General Public License as published by the +# Free Software Foundation, version 3. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License along +# with this program. If not, see + +<<"ASCIIDOC" + +Pull files from Android device to prepare a debugging sysroot +Inspired by: +https://fw4spl-org.github.io/fw4spl-blog/2015/07/27/Native-debugging-on-Android-with-QtCreator.html + +The goal is to have a local copy of the sysroot of the connected device. +For that we use the command `adb pull ` + +We will get a copy of: + +- `/system/lib/` +- `/vendor/lib/` +- `libc.so` +- `libcutils.so` + +As well as the binaries `linker` and `app_process` + +IMPORTANT: +from one device to another, the remote file `app_process` can be a binary file +or a symlink to a binary file - which is NOT ok for us. +That's so we will try to pull every known possible variants of `app_process`, +e.g. `app_process32` or `app_process_init` + +ASCIIDOC + + +## Define default value for variable, take two arguments, $1 variable name, +## $2 default variable value, if the variable is not already define define it +## with default value. +function define_default_value() +{ + VAR_NAME="${1}" + DEFAULT_VALUE="${2}" + + [ -z "${!VAR_NAME}" ] && export ${VAR_NAME}="${DEFAULT_VALUE}" +} + +define_default_value ANDROID_SERIAL "$(adb devices | head -n 2 | tail -n 1 | awk '{print $1}')" +define_default_value DEBUG_SYSROOT "${HOME}/Builds/debug_sysroot/${ANDROID_SERIAL}/" + +rm -rf "${DEBUG_SYSROOT}" + +for mDir in "/system/lib/" "/vendor/lib/"; do + mkdir -p "${DEBUG_SYSROOT}/${mDir}" + # adb pull doesn't behave like rsync dirA/ dirB/ so avoid nesting the + # directory by deleting last one before copying + rmdir "${DEBUG_SYSROOT}/${mDir}" + adb pull "${mDir}" "${DEBUG_SYSROOT}/${mDir}" +done + +# Retrieve the specific binaries - some of these adb commands will fail, since +# some files may not exist, but that's ok. + +mkdir -p "${DEBUG_SYSROOT}/system/bin/" +for mBin in "/system/bin/linker" "/system/bin/app_process" \ + "/system/bin/app_process_init" "/system/bin/app_process32" \ + "/system/bin/app_process64" ; do + adb pull "${mBin}" "${DEBUG_SYSROOT}/${mBin}" +done + +# Verify which variants of the specific binaries could be pulled +echo +echo "Found the following specific binaries:" +echo +ls -1 "${DEBUG_SYSROOT}/system/bin/"* +ls -1 "${DEBUG_SYSROOT}/system/lib/libc.so"* +ls -1 "${DEBUG_SYSROOT}/system/lib/libcutils.so"* +echo + +echo DEBUG_SYSROOT="${DEBUG_SYSROOT}" diff --git a/build_scripts/Android/start_gdbserver.sh b/build_scripts/Android/start_gdbserver.sh new file mode 100755 index 000000000..dce913568 --- /dev/null +++ b/build_scripts/Android/start_gdbserver.sh @@ -0,0 +1,101 @@ +#!/bin/bash + +# Script to start gdbserver on Android device and attach to retroshare-service +# +# Copyright (C) 2020 Gioacchino Mazzurco +# Copyright (C) 2020 Asociación Civil Altermundi +# +# This program is free software: you can redistribute it and/or modify it under +# the terms of the GNU Affero General Public License as published by the +# Free Software Foundation, version 3. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License along +# with this program. If not, see + +<<"ASCIIDOC" + +Start gdbserver on Android device and attach it to the retroshare service +process + +Inspired by: +https://fw4spl-org.github.io/fw4spl-blog/2015/07/27/Native-debugging-on-Android-with-QtCreator.html + +ASCIIDOC + + +## Define default value for variable, take two arguments, $1 variable name, +## $2 default variable value, if the variable is not already define define it +## with default value. +function define_default_value() +{ + VAR_NAME="${1}" + DEFAULT_VALUE="${2}" + + [ -z "${!VAR_NAME}" ] && export ${VAR_NAME}="${DEFAULT_VALUE}" +} + +define_default_value ANDROID_APK_PACKAGE "org.retroshare.service" +define_default_value ANDROID_PROCESS_NAME "org.retroshare.service:rs" +define_default_value ANDROID_SERIAL "$(adb devices | head -n 2 | tail -n 1 | awk '{print $1}')" +define_default_value GDB_SERVER_PORT 5039 + +adb_shell() +{ + adb shell run-as ${ANDROID_APK_PACKAGE} $@ +} + +## If not passed as environement variable try to determine gdbserver path +## shipped withing Android package +[ -z "${LIB_GDB_SERVER_PATH}" ] && +{ + for mUsualPath in \ + "/data/data/${ANDROID_APK_PACKAGE}/lib/libgdbserver.so" \ + "/data/app/${ANDROID_APK_PACKAGE}"*"/lib/arm64/libgdbserver.so" + do + adb_shell ls "${mUsualPath}" && + export LIB_GDB_SERVER_PATH="${mUsualPath}" && break + done +} + + +[ -z "${LIB_GDB_SERVER_PATH}" ] && +{ + cat <