From: Andrey Kvochko Date: Tue, 24 Oct 2017 13:01:06 +0000 (+0300) Subject: Changes after review X-Git-Tag: submit/tizen/20180620.112952^2~18 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=43ff3366c5a339336ba2c72abca907c21654e38d;p=sdk%2Ftools%2Fheaptrack.git Changes after review --- diff --git a/.gitignore b/.gitignore index 346e443..66189e0 100644 --- a/.gitignore +++ b/.gitignore @@ -15,7 +15,6 @@ perf.data perf.data.* callgrind.out.* .*kate-swp -*.rpm # from kdiff3 *.BACKUP.* diff --git a/README.md b/README.md index dfd5c1a..1e1e0bd 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,26 @@ ## Brief contents of the Guide +### Building and launching profiler in Docker + +Prerequisites: +* [Tizen SDK](https://developer.tizen.org/development/tizen-studio/download) is required to run the profiler. +* Your host machine should have Docker installed. For Ubuntu instructions, please see [the manual](https://docs.docker.com/engine/installation/linux/docker-ce/ubuntu/). + +Please, keep in mind: + +> If you would like to use Docker as a non-root user, you should now consider +> adding your user to the "docker" group with something like: +> +> `sudo usermod -aG docker your-user` + +1. When building in Docker, the first thing you need to do is to create a `coreclr-devel` directory and put coreclr-devel rpms for the CoreCLR versions you use on your devices in this folder. You can find out which version of CoreCLR is installed on your device using `rpm -qa` command. Alternatively, you can let docker download the latest `coreclr-devel` package from download.tizen.org, or, if you are building CoreCLR yourself, point the build script to the compiled CoreCLR source folder. If you choose one of these two options, leave the `coreclr-devel` folder empty and proceed to step 2. +2. Run +``` +sudo ./launch.sh org.tizen.example.HelloWorld.Tizen /opt/usr/home/owner/apps_rw/HelloWorld.Tizen/bin/HelloWorld.Tizen.exe +``` +to build the profiler and launch profiling of HelloWorld application. If you are running the profiler for the first time, you will be asked permission to move files around on the device in order to free up some disk space. You will also be asked to point the script to the location of "debuginfo" RPMs for the native libraries in which you want to see stack traces. + ### VM [[Details]](docs/DETAILED.md#download-and-unpack-vm-disk-image-from-this-page) 1\. Download and unpack VM image, start it in VirtualBox and connect with Tizen device @@ -30,8 +50,6 @@ For unpacking on Windows, please see [the details](docs/DETAILED.md#download-and [[SHA256 values for archive contents]](#checksums) -You can also build and run the profiler entirely in Docker. For instructions, please see [Docker Instructions](#docker-instructions) - ### Initialization of device for measurements [[Details]](docs/DETAILED.md#prepare-tizen-device-for-measurements) 2\. Put Tizen RPMs to VM's /home/ubuntu/device-rpms for: @@ -112,17 +130,6 @@ Next several views are graphs for different memory consumption statistics (also, Here, the "consumed" is used instead of "leaks", which is more precise. The "consumed" view shows memory consumption graph for top memory consuming function (separately, as shown in color, and also total consumption - the topmost graph). - - -## Docker Instructions - -1. When building in Docker, first thing you need to do is to create a `coreclr-devel` directory and put coreclr-devel rpms for the CoreCLR versions you use on your devices in this folder. You can find out which version of CoreCLR is installed on your device using `rpm -qa` command. Alternatively, you can let docker download the latest `coreclr-devel` package from download.tizen.org. If you choose this option, leave the `coreclr-devel` folder empty and proceed to step 2, but please make sure that the device also has the latest coreclr package installed. -2. Run -``` -./scripts/docker/heaptrack.sh org.tizen.example.HelloWorld.Tizen /opt/usr/home/owner/apps_rw/HelloWorld.Tizen/bin/HelloWorld.Tizen.exe -``` -to build the profiler and launch profiling of HelloWorld application. The rest of the steps are the same as in the Measurements section of this document. - ## Troubleshooting 1\. The heaptrack is built for one of latest Tizen Unified TM1 system. diff --git a/launch.sh b/launch.sh new file mode 100755 index 0000000..cd5c20b --- /dev/null +++ b/launch.sh @@ -0,0 +1,37 @@ +#!/bin/bash + +DEVICE_HEAPTRACK_PATH=/opt/usr/heaptrack +DEVICE_ARCH=armel +HEAPTRACK_DATA_DIR=~/.heaptrack +SCRIPTS_PATH=$(dirname $BASH_SOURCE)/scripts/docker +RES_FILE=$HEAPTRACK_DATA_DIR/res.gz +APP_ID=$1 +APP_PATH=$2 + +source "$SCRIPTS_PATH/../common.sh" +test_sdb_version + +source $SCRIPTS_PATH/heaptrack-build.sh $DEVICE_ARCH + +if [ "$?" != "0" ]; then + echo "Errors; see the log for details" + exit 1 +fi + +DOCKER_CONTAINER_HASH=$(docker create heaptrack:latest) + +$SDB root on +LAUNCH_GUI="true" + +$SCRIPTS_PATH/heaptrack-run.sh "$SDB" \ + "$DEVICE_HEAPTRACK_PATH" \ + "$DEVICE_ARCH" \ + "$HEAPTRACK_DATA_DIR" \ + "$DOCKER_CONTAINER_HASH" \ + "$SCRIPTS_PATH" \ + "$RES_FILE" \ + "$APP_ID" \ + "$APP_PATH" \ + "$LAUNCH_GUI" \ + "$CORECLR_BIN_DIR" + diff --git a/profiler/profiler/build.sh b/profiler/profiler/build.sh index 9f6e897..72c30f5 100755 --- a/profiler/profiler/build.sh +++ b/profiler/profiler/build.sh @@ -37,7 +37,7 @@ determine_cmake_arch() { fi done - echo "Unsupported architecture '$ARCH'. Must be one of $supported_cmake_archs." + echo "Unsupported architecture '$ARCH'. Must be one of ${supported_cmake_archs[@]}." fi elif [ "$coreclr_source" == "rpm" ]; then # determine architecture from RPM package @@ -50,7 +50,7 @@ determine_cmake_arch() { fi let arch_index=arch_index+1 done - echo "Unsupported architecture '$rpm_arch'. Must be one of $supported_rpm_archs." + echo "Unsupported architecture '$rpm_arch'. Must be one of ${supported_rpm_archs[@]}." exit 1 else usage diff --git a/scripts/common.sh b/scripts/common.sh new file mode 100755 index 0000000..a37688f --- /dev/null +++ b/scripts/common.sh @@ -0,0 +1,79 @@ +#!/bin/bash + +SDB=$(which sdb) + +read_one_of() { + local __prompt=$1 + local __options=$2 + local __result=$3 + local __tmp="" + local options_str="[$(echo ${__options[@]} | sed 's/ /\//g')]" + while [ true ]; do + read -p "$__prompt $options_str " __tmp + for opt in $__options; do + local lower_opt=$(echo "$opt" | awk '{ print(tolower($0)) }') + local lower_tmp=$(echo "$__tmp" | awk '{ print(tolower($0)) }') + if [ "$lower_opt" == "$lower_tmp" ]; then + export $__result="$opt" + return + fi + done + done +} + +read_file() { + local __prompt=$1 + local __result=$2 + local __tmp="" + while [ ! -f "$__tmp" ]; do + read -p "$__prompt" __tmp + if [ ! -f "$__tmp" ]; then + echo "Can't find file $__tmp" + fi + done + export $__result="$__tmp" +} + +read_dir() { + local __prompt=$1 + local __result=$2 + local __tmp="" + while [ ! -d "$__tmp" ]; do + read -p "$__prompt" __tmp + if [ ! -d "$__tmp" ]; then + echo "Can't find directory $__tmp" + fi + done + export $__result="$__tmp" +} + +read_consent() { + local __prompt=$1 + local __result=$2 + local __tmp="" + read_one_of "$__prompt" "Y n" __tmp + if [ "$tmp" == "Y" ]; then + export $__result=true + else + export $__result=false + fi +} + +test_sdb_version() { + read_file "sdb was not found. Enter sdb path [] " SDB + ver=( $($SDB version | sed -r 's/.*([0-9]+)\.([0-9]+)\.([0-9]+).*/\1 \2 \3/g') ) + if [[ "${ver[0]}" < "2" ]] || [[ "${ver[1]}" < "3" ]]; then + echo "Unsupported sdb version: ${ver[0]}.${ver[1]}.${ver[2]}. Please update sdb to at least 2.3.0" + exit 1 + fi + echo "Found sdb version ${ver[0]}.${ver[1]}.${ver[2]}" + + local num_devices=$($SDB devices | tail -n +2 | wc -l) + if [ "$num_devices" == "0" ]; then + echo "Error: no devices attached" + exit 1 + elif [ "$num_devices" != "1" ]; then + echo "Error: only one device must be attached" + exit 1 + fi +} \ No newline at end of file diff --git a/scripts/docker/heaptrack-build.sh b/scripts/docker/heaptrack-build.sh new file mode 100755 index 0000000..c9ec192 --- /dev/null +++ b/scripts/docker/heaptrack-build.sh @@ -0,0 +1,63 @@ +#!/bin/bash + +DEVICE_ARCH=$1 +SCRIPTS_PATH=$(dirname $BASH_SOURCE) + +if [ ! -f "$SDB" ]; then + source "$SCRIPTS_PATH/../common.sh" +fi + +test_coreclr_devel() { + coreclr_rpms=$(ls ${SCRIPTS_PATH}/../../coreclr-devel/coreclr-devel-*.rpm 2>/dev/null) + if [ -z "$coreclr_rpms" ]; then + echo "coreclr-devel rpms not found in ${SCRIPTS_PATH}/../../coreclr-devel ." + read_consent "Do you want to download the latest coreclr-devel package?" DOWNLOAD_CORECLR_DEVEL + if $DOWNLOAD_CORECLR_DEVEL; then + coreclr_source="rpm" + return + fi + + read_dir "Enter the source location of a compiled coreclr repository. The binaries in the repository \ +must match those on the device. [] " CORECLR_SRC_DIR + + read_one_of "Enter the CoreCLR build type" "Release Debug Checked" coreclr_build_type + export CORECLR_BIN_DIR="$CORECLR_SRC_DIR/bin/Product/Linux.$DEVICE_ARCH.$coreclr_build_type" + if [ ! -d "$CORECLR_BIN_DIR" ]; then + echo "Can't find CoreCLR binaries in '$CORECLR_BIN_DIR'" + exit 1 + fi + coreclr_source="manual" + else + for coreclr_rpm in $coreclr_rpms; do + echo "Found $(basename $coreclr_rpm)" + done + coreclr_source="rpm" + fi +} + +build_container() { + temp_dir="$SCRIPTS_PATH/../../.coreclr" + if [ "$coreclr_source" == "manual" ]; then + base_dir="$(basename $CORECLR_BIN_DIR)" + mkdir -p $temp_dir/bin/Product/$base_dir/lib + mkdir -p $temp_dir/src + rsync -a --exclude=".nuget" --exclude="test*" $CORECLR_SRC_DIR/src/ $temp_dir/src + rsync -a $CORECLR_BIN_DIR/lib/* \ + $temp_dir/bin/Product/$base_dir/lib + rsync -a $CORECLR_BIN_DIR/inc \ + $temp_dir/bin/Product/$base_dir/inc + + fi + + docker build --build-arg CORECLR_SOURCE="$coreclr_source" \ + --build-arg BUILD_TYPE="$coreclr_build_type" \ + --build-arg ARCH="$DEVICE_ARCH" \ + -t heaptrack:latest $SCRIPTS_PATH/../.. + if [ ! "$?" -eq "0" ]; then + echo "build errors; see the log for details" + exit 1 + fi +} + +test_coreclr_devel +build_container \ No newline at end of file diff --git a/scripts/docker/heaptrack-run.sh b/scripts/docker/heaptrack-run.sh index 852c483..39d156f 100755 --- a/scripts/docker/heaptrack-run.sh +++ b/scripts/docker/heaptrack-run.sh @@ -14,6 +14,12 @@ LAUNCH_GUI=${10} CORECLR_BIN_DIR=${11} DEVICE_CORECLR_PATH="/usr/share/dotnet/" +$SCRIPTS_PATH/../prepare-device.sh +if [ "$?" != "0" ]; then + "Errors; please see the log for details" + exit 1 +fi + IS_FOUND_APP=$($SDB shell "app_launcher -l | cut -d \"'\" -f 4 | grep -q '^${APP_ID}$'; echo \$?" | tr -d "[:space:]") if [ "$IS_FOUND_APP" != "0" ]; then echo "'${APP_ID}' application not found at device" diff --git a/scripts/docker/heaptrack.sh b/scripts/docker/heaptrack.sh deleted file mode 100755 index fba2600..0000000 --- a/scripts/docker/heaptrack.sh +++ /dev/null @@ -1,112 +0,0 @@ -#!/bin/bash - -SDB=$(which sdb) -DEVICE_HEAPTRACK_PATH=/opt/heaptrack -DEVICE_ARCH=armel -HEAPTRACK_DATA_DIR=~/.heaptrack -SCRIPTS_PATH=$(dirname $BASH_SOURCE) -RES_FILE=$HEAPTRACK_DATA_DIR/res.gz -APP_ID=$1 -APP_PATH=$2 -DOWNLOAD_CORECLR_DEVEL="" -CORECLR_SRC_DIR="" -CORECLR_BIN_DIR="" - -test_sdb_version() { - if [ ! -f $SDB ]; then - echo "sdb not found. Please make sure that sdb is in your PATH." - exit 1 - fi - ver=( $($SDB version | sed -r 's/.*([0-9]+)\.([0-9]+)\.([0-9]+).*/\1 \2 \3/g') ) - if [[ "${ver[0]}" < "2" ]] || [[ "${ver[1]}" < "3" ]]; then - echo "Unsupported sdb version: ${ver[0]}.${ver[1]}.${ver[2]}. Please update sdb to at least 2.3.0" - exit 1 - fi - echo "Found sdb version ${ver[0]}.${ver[1]}.${ver[2]}" -} - -test_coreclr_devel() { - coreclr_rpms=$(ls ${SCRIPTS_PATH}/../../coreclr-devel/coreclr-devel-*.rpm 2>/dev/null) - if [ -z "$coreclr_rpms" ]; then - echo "coreclr-devel rpms not found in ${SCRIPTS_PATH}/../../coreclr-devel ." - while [ "$DOWNLOAD_CORECLR_DEVEL" != "y" ] && [ "$DOWNLOAD_CORECLR_DEVEL" != "n" ]; do - read -p "Do you want to download the latest coreclr-devel package? [Y/n] " DOWNLOAD_CORECLR_DEVEL - if [ -z "$DOWNLOAD_CORECLR_DEVEL" ]; then - DOWNLOAD_CORECLR_DEVEL="y" - fi - DOWNLOAD_CORECLR_DEVEL=$(echo $DOWNLOAD_CORECLR_DEVEL | awk '{ print(tolower($0)) }') - done - - if [ "$DOWNLOAD_CORECLR_DEVEL" == "y" ]; then - coreclr_source="rpm" - return - fi - - read -p "Enter the source location of a compiled coreclr repository. The binaries in the repository \ -must match those on the device. [] " CORECLR_SRC_DIR - if [ ! -d "$CORECLR_SRC_DIR" ] || [ ! -d "$CORECLR_SRC_DIR/src" ]; then - echo "Can't find CoreCLR source in '$CORECLR_SRC_DIR'" - exit 1 - fi - - coreclr_build_type="" - read -p "Enter the CoreCLR build type [Release/Debug/Checked] " coreclr_build_type - CORECLR_BIN_DIR="$CORECLR_SRC_DIR/bin/Product/Linux.$DEVICE_ARCH.$coreclr_build_type" - if [ ! -d "$CORECLR_BIN_DIR" ]; then - echo "Can't find CoreCLR binaries in '$CORECLR_BIN_DIR'" - exit 1 - fi - coreclr_source="manual" - else - for coreclr_rpm in $coreclr_rpms; do - echo "Found $(basename $coreclr_rpm)" - done - coreclr_source="rpm" - fi -} - -build_container() { - temp_dir="$SCRIPTS_PATH/../../.coreclr" - if [ "$coreclr_source" == "manual" ]; then - base_dir="$(basename $CORECLR_BIN_DIR)" - mkdir -p $temp_dir/bin/Product/$base_dir/lib - mkdir -p $temp_dir/src - rsync -a --exclude=".nuget" --exclude="test*" $CORECLR_SRC_DIR/src/ $temp_dir/src - rsync -a $CORECLR_BIN_DIR/lib/* \ - $temp_dir/bin/Product/$base_dir/lib - rsync -a $CORECLR_BIN_DIR/inc \ - $temp_dir/bin/Product/$base_dir/inc - - fi - - docker build --build-arg CORECLR_SOURCE="$coreclr_source" \ - --build-arg BUILD_TYPE="$coreclr_build_type" \ - --build-arg ARCH="$DEVICE_ARCH" \ - -t heaptrack:latest $SCRIPTS_PATH/../.. - if [ ! "$?" -eq "0" ]; then - echo "build errors; see the log for details" - exit 1 - fi -} - -test_sdb_version -test_coreclr_devel -build_container - -DOCKER_CONTAINER_HASH=$(docker create heaptrack:latest) - -$SDB root on -LAUNCH_GUI="true" - -$SCRIPTS_PATH/heaptrack-run.sh "$SDB" \ - "$DEVICE_HEAPTRACK_PATH" \ - "$DEVICE_ARCH" \ - "$HEAPTRACK_DATA_DIR" \ - "$DOCKER_CONTAINER_HASH" \ - "$SCRIPTS_PATH" \ - "$RES_FILE" \ - "$APP_ID" \ - "$APP_PATH" \ - "$LAUNCH_GUI" \ - "$CORECLR_BIN_DIR" - diff --git a/scripts/heaptrack.sh b/scripts/heaptrack.sh index 94303dd..c3ab777 100755 --- a/scripts/heaptrack.sh +++ b/scripts/heaptrack.sh @@ -1,7 +1,7 @@ #!/bin/bash SDB=/home/ubuntu/tizen-studio/tools/sdb -DEVICE_HEAPTRACK_PATH=/opt/heaptrack +DEVICE_HEAPTRACK_PATH=/opt/usr/heaptrack HEAPTRACK_FOR_DEVICE_HOST_PATH=/home/ubuntu/heaptrack-arm HEAPTRACK_FOR_HOST_PATH=/home/ubuntu/heaptrack SCRIPTS_PATH=/home/ubuntu/heaptrack-scripts diff --git a/scripts/prepare-device.sh b/scripts/prepare-device.sh index 757acb1..8db20f7 100755 --- a/scripts/prepare-device.sh +++ b/scripts/prepare-device.sh @@ -1,17 +1,38 @@ -#!/bin/bash -x +#!/bin/bash -SDB=/home/ubuntu/tizen-studio/tools/sdb -RPMS_DIR=/home/ubuntu/device-rpms -SCRIPTS_PATH=/home/ubuntu/heaptrack-scripts +SCRIPTS_PATH=$(dirname $BASH_SOURCE) -$SDB root on +if [ ! -f "$SDB" ]; then + source $SCRIPTS_PATH/common.sh + test_sdb_version + if [ $? != 0 ]; then + exit 1 + fi +fi if [ "$($SDB shell 'ls -d1 /opt/usr/rpms 2> /dev/null')" != "" ]; then - echo "The script already completed for the device. Please, don't use it second time until reset of the device to initial state" + echo "Device is already prepared to run the profiler." + exit 0 +fi - exit 1 +echo "This step will move things around on the device in order to get additional space" +echo "required to run the profiler. What will be moved:" +echo " - /usr/share/dotnet -> /opt/usr/dotnet" +echo " - /usr/share/dotnet-tizen -> /opt/usr/dotnet-tizen" +echo " - /usr/lib/debug -> /opt/usr/lib/debug" +echo " - /usr/src/debug -> /opt/usr/src/debug" +echo "Symlinks to new locations will be created in old locations." +5 +read_consent "Do you want to proceed?" consent +if ! $consent; then + echo "Can not proceed without preparing the device" + exit 1 fi +read_dir "Please enter the location of debug RPMs [] " RPMS_DIR + +$SDB root on + $SDB shell "mkdir /opt/usr/rpms" $SDB push $RPMS_DIR/* /opt/usr/rpms