I have following AOSP project setup
1) I have test.cpp in (AOSP root directory)/vendor/myProject/test.cpp
2) In Android.mk i have used
LOCAL_CFLAGS += -g -fprofile-arcs -ftest-coverage
LOCAL_LDFLAGS += -lgcov
3) When I compile the code i get test.gcno in:
(AOSP root directory)/out/target/product/generic/obj/EXECUTABLES/myProject_intermediates
4) Then i put the test on device (adb sync)
5) Then on device i have used following:
export GCOV_PREFIX=/vendor
export GCOV_PREFIX_STRIP=13 (to strip down the un-necessary path)
6) I run the test ./system/bin/test and i get test.gcda file on
device (shell) /vendor/test.gcda
7) I copy the test.gcda (from device) to my build directory (/out/target/product/generic/obj/EXECUTABLES/myProject_intermediates) where i already have test.gcno
8) Now i am in /out/target/product/generic/obj/EXECUTABLES/myProject_intermediates
Then run gcov as follows:
(AOSP root
directory)/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin/arm-eabi-gcov
test
For this i get output as follows:
File 'vendor/myProject/test.cpp' Lines executed:23.00% of 223
vendor/myProject/test.cpp:creating 'test.cpp.gcov'
vendor/myProject/test.cpp:cannot open source file
Can anybody help me on how to solve this. It says test.cpp:cannot open source file
gcov is not generating complete report. I have also checked -b option by specifying the path to source as follows:
(AOSP root
directory)/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin/arm-eabi-gcov
-b (AOSP root directory)/vendor/myProject test
It didn't worked.
I guess the problem is because of distributed files (gcno,gcda,test.cpp) in different directories.
Thanks
Solution is while building the test in which directory you were, you should be in the same directory while running gcov later, then all the .gcov files will be created successfully.
For example:
Project directory : android/frameworks/Myproj
In this you have test.cpp and Android.mk
Then say suppose from android directory you'll build the app or test.cpp, i.e. android$
Then the *.gcno files will be present in android/out/Myproj_Intermediates/
You will get the *.gcda files by running app in device, you will bring that *.gcda files from device to folder android/out/Myproj_intermediates/
Now to run gcov on these:
You should be in the android directory (since you built app from there)
android$ ./prebuilts/gcc/linux-x86/arm/arm-eabi-4.6/bin/arm-eabi-gcov \
-o out/Myproj_intermediates/ -a frameworks/Myproj/test.cpp -b -c
There has been a better approach in AOSP for several months now.
Add LOCAL_NATIVE_COVERAGE := true to your makefile.
$ export NATIVE_COVERAGE := true
Build, sync, run.
$ acov
acov will pull all the coverage files off the device, put them in the right place, and lcov (iirc this will prompt you to install if you don't already have it), and generate and HTML report for you.
Related
I have setup a debug ROM on an Android device, and enabled the DDMS Native Heap in search for a libgdx memory leak.
I now have a trace, but no source code attached to follow the lead.
I downloaded libgdx source code.
How do I build it enabling gdb tracing so I can follow the code referenced by the trace ?
Update:
I built the debug .so libgdx from source
To do this, I modified the file:
libgdx/gdx/jni/build-android32.xml
Adding to the compile-natives target
I also added APP_OPTIM := debug to the Application.mk in the same folder
And added '-g' to the Android.mk file in the same folder:
LOCAL_CFLAGS := -g $(LOCAL_C_INCLUDES:%=-I%) -O2 -Wall -D__ANDROID__
This, indeed, produces a dbg libgdx.so dynamic library place in
libgdx/gdx/libs/armeabi
Although I am getting closer, I still cannot get the name of the function that is loading memory.
I am using arm-linux-androideabi-addr2line and the Hex address of the function, but it prints
??
Download the Android Source and build it.
Point DDMS to the libs with debug symbols. On the command line:
export ANDROID_SYMBOLS=$ANDROID_SOURCE/out/target/product/flo/symbols/system/lib
Note that $ANDROID_SOURCE refers to the location where you built the Android source.
start DDMS from that shell
$ddms
Now you should see the native traces on ddms.
I also built libgdx from source and added $LIBGDX_SOURCE/libgdx/gdx/obj/local/armeabi/libgdx.so
to $ANDROID_SOURCE/out/target/product/flo/symbols/system/lib to see the method names for libgdx.so.
Preliminaries
You need to set the device to debug memory
adb root
adb shell setprop libc.debug.malloc 1
adb shell stop
adb shell start
The device must be rooted or with a dbg ROM.
I need to add the timetest directory's executable to the system.img file so that I can access the command from the shell. The location is at : https://android.googlesource.com/platform/system/extras/+/android-4.4.4_r1/tests/timetest/. So what I did was to go into the timetest directory and issue the following command:
mm snod
The output was as follows:
PRODUCT_COPY_FILES device/generic/goldfish/data/etc/apns-conf.xml:system/etc/apns-conf.xml ignored.
make: Entering directory `/home/username/android_built/android'
target thumb C: timetest <= frameworks/base/cmds/timetest/timetest.c
target StaticExecutable: timetest (out/target/product/hammerhead/obj/EXECUTABLES/timetest_intermediates/LINKED/timetest)
target Symbolic: timetest (out/target/product/hammerhead/symbols/sbin/timetest)
target Strip: timetest (out/target/product/hammerhead/obj/EXECUTABLES/timetest_intermediates/timetest)
Install: out/target/product/hammerhead/root/sbin/timetest
make: Leaving directory `/home/username/android_built/android'
The file installation part has been left out for clarity.
The following output is after I tried copying the timetest into frameworks/base/cmds as detailed in this question : android AOSP, adding new executable [.c] code. I also tried it directly.
I then looked at the entire phone including the xbin,bin directories . I also used find / -name "timetest", but the executable is nowhere to be found. What am I doing wrong?
I'm not actually sure how you are installing timetest to your device, but if you are just adb pushing the result to your device then you will likely have a hard time running that.
If you look at the Android.mk file for timetest you will see that it is labeled as "optional"
LOCAL_MODULE_TAGS := optional
However after grepping through all the make files, there is no build variant which includes this in a build. If you have your own device make file you can add it there, but if you just want to make this work quickly you can add it to the list of PRODUCT_PACKAGES in the build/target/product/core_minimal.mk file. There will be a list that looks something like:
PRODUCT_PACKAGES += \
BackupRestoreConfirmation \
DownloadProvider \
HTMLViewer \
MediaProvider \
Just add timetest into that list. After that do a make installclean and rebuild your device and you should have timetest included in sbin.
I'm at the end of my rope on this one.
I'm new to Android development. I've read the GCC install documentation and parts of Embedded Android. I'm trying to cross-compile gcc 4.7 using an Android NDK toolchain built with the make-standalone-toolchain.sh script. I'm using the gcc and binutils source files from the NDK toolchain sources.
I copied the gcc-4.7 and binutils-2.23 into a directory gcc-src and created a 'build' directory alongside both, as follows:
gcc-src/gcc-4.7
gcc-src/binutils-2.23
gcc-src/build
I've symlinked the sources for
bfd,
gas,
gprof,
ld,
gprof
opcodes
from binutils to the gcc-4.7 source directory. I also ran the script in contrib/ that downloads the relevant sources for
gmp,
mpfr
mpc
and creates the appropriate symlinks
I've run configure with the (latest) following options:
sh ../gcc-4.7/configure --prefix=/usr/arm --disable-option-checking --host=arm-linux-eabi
--target=arm-linux-eabi --with-sysroot=/usr/sysroot --with-build-sysroot=/usr/sysroot --with-build-time-tools=/usr/bin --program-prefix=arm-
--disable-multilib --with-cpu=arm7 --enable-languages=c,c++,lto --disable-werror --disable-nls CC=arm-linux-androideabi-gcc GCC=arm-linux-androideabi-gcc
CFLAGS='-Wall -g -mfloat-abi=softfp -mbionic -mandroid -Wl,-lsupc++ -Wl,-lgnustl_shared'
CPPFLAGS='-Wall -g -mbionic -mandroid' LDFLAGS='-Wl,-lsupc++ -Wl,-lgnustl_shared' CXX=arm-linux-androideabi-g++
LD=arm-linux-androideabi-ld STRIP=arm-linux-androideabi-strip OBJDUMP=arm-linux-androideabi-objdump READELF=arm-linux-androideabi-readelf
AS=arm-linux-androideabi-as NM=arm-linux-androideabi-nm
LIBS='-lc -ldl -lm' CC_FOR_TARGET=arm-linux-androideabi-gcc CPP_FOR_TARGET=arm-linux-androideabi-gcc CXX_FOR_TARGET=arm-linux-androideabi-g++
GCC_FOR_TARGET=arm-linux-androideabi-gcc RANLIB_FOR_TARGET=arm-linux-androideabi-gcc-ranlib LD_FOR_TARGET=arm-linux-androideabi-ld
AS_FOR_TARGET=arm-linux-androideabi-as NM_FOR_TARGET=arm-linux-androideabi-gcc-nm AR_FOR_TARGET=arm-linux-androideabi-gcc-ar
READELF_FOR_TARGET=arm-linux-androideabi-readelf
OBJDUMP_FOR_TARGET=arm-linux-androideabi-objdump STRIP_FOR_TARGET=arm-linux-androideabi-strip
host_configargs=--with-headers=/usr/sysroot/usr/include target_configargs=/usr/sysroot/usr/include
When I run make -d...or make -d all-host...it constantly fails when it tries to compile gen-fac_ui.c because it can't find the includes stdio.h, stdint.h or string.h.
I'll add the exact error tomorrow after I re-set my build directory and start again, but I wanted to post the details and problem tonight before I pass out.
Any help...is greatly appreciated. I'm at a loss on this one.
QUICK NOTE: I noticed that the binutils src directory contains an include/ folder...I'll try symlinking that into the gcc src directory and running 'make distclean' then '../gcc-4.7/configure && make again.'
UPDATE: symlinking include/ did not fix the problem. Here's the error I'm continuously getting
make[2]: Entering directory `/project/android/tc-src/gcc/gcc-src/build/gmp'
gcc `test -f 'gen-fac_ui.c' || echo '../../gcc-4.7/gmp/'`gen-fac_ui.c -o gen-fac_ui
Putting child 0x007ddd30 (gen-fac_ui) PID 25531 on the chain.
Live child 0x007ddd30 (gen-fac_ui) PID 25531
../../gcc-4.7/gmp/gen-fac_ui.c:20:19: error: stdio.h: No such file or directory
../../gcc-4.7/gmp/gen-fac_ui.c:21:20: error: stdlib.h: No such file or directory
In file included from ../../gcc-4.7/gmp/gen-fac_ui.c:23:
../../gcc-4.7/gmp/dumbmp.c:42:20: error: string.h: No such file or directory
In file included from ../../gcc-4.7/gmp/gen-fac_ui.c:23:
I successfully compiled gen-fac_ui by doing the following:
Uninstalling the build gcc which is not (I think) needed as I'm using the cross-compiler toolchain generated by the make-standalone-toolchain.sh script from the Android NDK
Configuring the appropriate variables to set up the cross-compiler tools as the BUILD tools.
I have a different problem now, which I'll post in a different question. Basically, while gen-fac_ui compiles, it (of course) won't run.
I am unable to build helloWorld sample to get .so to run it in eclipse. I have imported project successfully and changed variable to my root path as required. this is my build_native.sh. I am pasting the only change I made in that file
NDK_ROOT_LOCAL=/cygdrive/e/android-ndk-r8
COCOS2DX_ROOT_LOCAL=/cygdrive/e/cocos2d
And my NDK is working fine because I have executed HelloWorld sample of NDK successfully. My SDK version is 20 and NDK version is 8 and I am using cygwin above than 1.7.. I have executed the chown on my NDK directory.. But when I run the command ./build_native.sh in HelloWorld sample program for cocos2d I get this error
E:/android-ndk-r8/toolchains/arm-linux-androideabi-4.4.3/prebuilt/windows/bin/../lib/gcc/arm- linux-androideabi/4.4.3/../../../../arm-linux-androideabi/bin/ld.exe: ./obj/local/armeabi/png.a: No such file: Permission denied
collect2: ld returned 1 exit status
and when I search for png.a in my NDK directory window can't locate that file. I am confused whether it's a permission error or File isn't there. But I have the latest NDK if file isn't there how come anyone will able to run cocos2d-x??? Need Help!!!
It seems like the permissions on built files were missing when I tried as well.
$ ls -l obj/local/armeabi/png.a
---------- 1 someuser Domain Users 912618 Jul 12 18:23 obj/local/armeabi/png.a
There is a link suggested on the forum which doesn't seem to be accessible right now.
Anyway, to fix, you can set the permission on the files.
$ cd obj/local/armeabi/
$ chmod 664 *.a
$ cd ../../..
Edit: A better fix may be to set the default permissions in /etc/fstab to
none /cygdrive cygdrive binary,noacl,posix=0,user 0 0
Following this, you should be able to run ./build_native.sh.
A command you could use to locate all files below the current directory which have no (read/write) permission available on them is find . -type f -perm 0
See this answer to set write permissions on all files below your working directory.
Consider going through a tutorial on chmod to understand the concept of permissions in linux/unix in case you're unfamiliar with them.
I have a Device on which I installed Android Gingerbread 2.3.4
Here i want to run C executable file on android device
I am able to run android NDK application on this Device and it runs perfect.
But I want to run only one hello.c executable file on the Device.
/* #includes #defines ... */
int main(){
// Do something when this is executed
return 0;
}
Is there any way to compile this file with Android NDK tool chain so I can run this file's executable?
I found one thing here but this is not working for me. I am using Android NDK, Revision 7b for Linux.
There is no directory structure like this.
First, let me say that my answer is dependent on your using NDK r7b (it'll work for r7c as well) on Linux (change paths appropriately for other systems).
Edit: Last tested with NDK r8e on Linux and Nexus 4 with adb from SDK Platform-Tools Rev 18 on Windows 7 (latest as of 2013-07-25) without root access.
Yet Another Edit: Please read this question for altering my instruction for native binaries that need to run on Android 5.0(Lollypop) and later.
Go to $NDK_ROOT (The topmost folder of NDK zip when unzipped).
Copy $NDK_ROOT/samples/hello-jni directory as $NDK_ROOT/sources/hello-world.
Go to $NDK_ROOT/sources/hello-world.
Edit AndroidManifest.xml to give the application an appropriate name (This is optional).
Go to $NDK_ROOT/sources/hello-world/jni. This is where the source code is.
Edit hello-jni.c, remove all the code, and put in your hello world code. Mine is:#include
int main( int argc, char* argv[])
{
printf("Hello, World!");
return 0;
}
Edit Android.mk and change the line include $(BUILD_SHARED_LIBRARY) to include $(BUILD_EXECUTABLE). You can also change the LOCAL_MODULE line to the name you want for your executable(default is hello-jni)
Go back to $NDK_ROOT/sources/hello-world
Run ../../ndk-build to create the executable.
Copy it from $NDK_ROOT/sources/hello-jni/libs/armeabi/hello-jni to /data/local/tmp on the Android device and change it's permissions to 755 (rwxr-xr-x). If you changed the LOCAL_MODULE line in $NDK_ROOT/sources/hello-world/jni/Android.mk, the executable name will be the new value of LOCAL_MODULE instead of hello-jni. (All this is done via adb from the Android SDK.)
Execute the binary with full path as /data/local/tmp/hello-jni, or whatever you named it to.
And you're done( and free to start on the documentation in $NDK_ROOT/docs to get a better idea of what to do).
The best/easiest place to put a executable is /data/local. You'll also need to chmod the binary as executable. Often you'll also need to do this in two steps to get the binary from /sdcard/ to /data/local:
$ adb push mybin /sdcard/
$ adb shell
$ cp /sdcard/mybin /data/local/mybin
$ cd /data/local
$ chmod 751 mybin
Caveats:
Not all systems have cp. You can use cat if this is the case:
$ cat /sdcard/mybin > /data/local/mybin
Some systems don't allow write in /data/local for the "shell" user. Try /data/local/tmp
the "/sdcard" location is not executable, meaning that any file there is not executable at all.
the only way to "adb push" executable would be to put them in "/data/local", which should be writable for adb, and allow execution for anyone.
I recently had the same problem on a new nexus-5. I'd like to add that /data/local was not writable by the user ("shell", uid 2000) I got with adb shell. But putting the executable in the subdirectory /data/local/tmp/ worked fine.
In a nutshell,
First, to cross-compile your C code from your host machine, use NDK toolchain with sysroot option and position independent option -fPIE -pie.
$NDKROOT/toolchains/aarch64-linux-android-4.9/prebuilt/darwin-x86_64/bin/aarch64-linux-android-gcc \
--sysroot=$NDKROOT/platforms/android-22/arch-arm64 -fPIE -pie main.c -o main
the arch part arrch64 or arch-arm64, the toolchain version part 4.9, platform version part android-22, and the binary format for your host machine darwin-x86_64 may vary by your environment.
Second, push your binary under /data/local/tmp and execute it from adb shell.