android ndk debug trap - android

In NDK (Only-native-C++) applications what is the correct way to set a programmatic debug trap? I mean stopping the application with possiblity to examine call stack, variables, etc.
For instance, under WIN32 debug trap in my GameEngine is declared as
#define DIE() __asm{ int 3 }
and for iOS it's
# if TARGET_IPHONE_SIMULATOR
# define DIE() {__asm__("int3");}
# else
# define DIE() {__asm__("trap");}
# endif
What would be a correct one for an Android NDK application?

__android_log_assert(...) from "android/log.h" should do the work.
This should break you into debugger since it raises SIGTRAP.
See http://mobilepearls.com/labs/native-android-api/ for a usage summary.

#include <signal.h>
raise(SIGTRAP);
or like in http://androidxref.com/5.0.0_r2/xref/system/core/liblog/logd_write.c function: __android_log_assert
__builtin_trap();

Related

'sizeof(off_t) != 8' when compiling libfuse for android

I'm trying to compile libfuse with NDK, my environment:
Win10(64bit) + NDK(r14b,64bit) + libfuse(3.1.0)
Error occurs in fuse_common.h, it checks size of off_t:
$ ndk-build
[armeabi-v7a] Compile thumb : fuse <= buffer.c
In file included from jni/../../libfuse/lib/buffer.c:15:
In file included from jni/../../libfuse/lib/fuse_i.h:9:
In file included from jni/../../libfuse/include\fuse.h:19:
jni/../../libfuse/include/fuse_common.h:745:13: error: bit-field
'_fuse_off_t_must_be_64bit' has negative width (-1)
{ unsigned _fuse_off_t_must_be_64bit:((sizeof(off_t) == 8) ? 1 : -1); };
^
1 error generated.
make: *** [obj/local/armeabi-v7a/objs/fuse/__/__/libfuse/lib/buffer.o] Error 1
here's the check in fuse_common.h:
struct _fuse_off_t_must_be_64bit_dummy_struct \
{ unsigned _fuse_off_t_must_be_64bit:((sizeof(off_t) == 8) ? 1 : -1); };
I searched on google, there's _FILE_OFFSET_BITS=64 definition, which can be used to change the size of off_t, I have this defined my 'Android.mk' file:
LOCAL_CFLAGS := \
....
-D_FILE_OFFSET_BITS=64 \
....
And even add this line at the beginning of fuse_common.h
#define _FILE_OFFSET_BITS 64
Still not working, how to fix it?
Update to NDK r15c. _FILE_OFFSET_BITS=64 works from there on out.
Note that most off64_t system calls weren't available until android-21. If your minSdkVersion is set below that and you use _FILE_OFFSET_BITS=64, many functions will not be available.
NOTE Provided solution is much like workaround, see #Dan's answer for reliable and official way to get 64-bit off_t.
On Android off_t is always 32-bit length, and there is no preprocessor macro that controls its size. (Though it is true only for NDK development since modern bionic allow to configure off_t size at compile time). And because of this you cannot compile your library directly.
But I guess there is some way to workaround it. Android NDK offers non-POSIX extended type - off64_t, and also it provides a complementary set of library functions that accept it instead of off_t. They are distinguished by 64 suffix, i.e. lseek64(), mmap64(). So to make things work you may try to add global configuration header to your project:
/* let off_t to be a 64-bit length */
typedef off64_t off_t;
/* use appropriate versions of system functions */
/* list here only functions that have off_t parameters and are used by your library */
#define mmap mmap64
#define lseek lseek64
And of course keep in mind that compiled code now is linked against *64() functions instead of regular ones and any public interfaces expect off64_t instead of off_t.

Call shell command after asm file generation in cmake

In android mk files it is possible to call a shell command right after generating assembly files with LOCAL_FILTER_ASM.
I was wondering is there any workaround to have something similar in cmake?
I admit I had lookup what LOCAL_FILTER_ASM does.
So the following is my piece of code (same functionality just in CMake):
cmake_minimum_required(VERSION 3.0)
project(LocalFilterASM C ASM)
set(LOCAL_FILTER_ASM "cp")
string(
REPLACE
"<ASSEMBLY_SOURCE>" "<OBJECT>.S.original"
MY_CREATE_ASSEMBLY "${CMAKE_C_CREATE_ASSEMBLY_SOURCE}"
)
string(
REPLACE
"<SOURCE>" "<OBJECT>.S"
MY_COMPILE_OBJECT "${CMAKE_ASM_COMPILE_OBJECT}"
)
set(
CMAKE_C_COMPILE_OBJECT
"${MY_CREATE_ASSEMBLY}"
"${LOCAL_FILTER_ASM} <OBJECT>.S.original <OBJECT>.S"
"${MY_COMPILE_OBJECT}"
)
file(WRITE main.c "int main(void) { return 0; }")
add_executable(${PROJECT_NAME} main.c)
This just takes some of the existing CMake compiler rules and combines it into a new multi-line rule for CMAKE_C_COMPILE_OBJECT. Please note that this will only work with CMake's makefile generators.
It's very hard to say since you haven't provided any example of what you currently have.
However, you can use the add_custom_command() function to add before and after scripts to any target (see the bottom of the page in the "Build Events" section for the syntax you want).

Android device configuration for AOSP

I've downloaded Android source code. Now I want to make it for my own device (LG GT540). I heard that you need to create some 'Device configuration' for that. Although several developers have already created device configurations for my device, but I want to create my own, just for learning.I saw a lot of files like BoardConfig.mk, AndroidProducts.mk, etc. But don't know what they do. Besides they contain a lot of configurations. Over that, there's not a good documentation for that.Can anyone experienced with Android porting and device configurations help me?
Right... So you want to build your own device tree, read on.
Disclaimer: this is by no means complete, and there will be omissions as have explained all this top of my head and copied pasted certain bits that I have here on my own device tree.
The device tree, for example, /device/lg/gt540would consist of the following make files:
Android.mk - this will tell the build system to include and to build sources specifically for your device. See below, for an example. This is dependant on the device and hardware, you could have libsensors, liblights, libcamera subdirectories under the example device tree, i.e. /device/lg/gt540/libsensors, /device/lg/gt540/liblights, /device/lg/gt540/libcamera etc.
AndroidBoard.mk - this is for the kernel, the build system uses that to drop the kernel image in place (more about this in a few minutes)
AndroidProducts.mk - specifies the appropriate device's make file, to use for building. i.e. /device/lg/gt540/device_gt540.mk, this is specific also.
device_xxxxx.mk - specifies the properties and extras to copy over into the final output, in this case, it could be for example, device_gt540.mk
BoardConfig.mk - This is the meat of it all, this is where compiler conditional flags are set, partition layouts, boot addresses, ramdisk size, and so on.
Lets peek into each of those to give a glance as to where it all fits in.
Android.mk:
ifeq ($(TARGET_BOOTLOADER_BOARD_NAME),xxxxx)
include $(call all-named-subdir-makefiles, recovery libsensors liblights libcamera ....)
endif
This is how the build will use that to build recovery, sensors, lights and camera (of course there will be more), its saying 'Yo Builder, go into each of the directories specified, and build the respective sources plskthxbai'
AndroidBoard.mk:
LOCAL_PATH := device/lg/gt540/
#
# Boot files
#
TARGET_PREBUILT_KERNEL := $(LOCAL_PATH)/kernel
file := $(INSTALLED_KERNEL_TARGET)
ALL_PREBUILT += $(file)
$(file): $(TARGET_PREBUILT_KERNEL) | $(ACP)
$(transform-prebuilt-to-target)
Now this, is telling the build system, to be able to drop this kernel into the out/target/product/lg/gt540 (notice the correlation with the device tree directory?)
AndroidProducts.mk:
PRODUCT_MAKEFILES := \
$(LOCAL_DIR)/device_gt540.mk
Its telling the build as in 'Yo Builder, read that device make file please and process it upon completion of build.'
*device_xxxxx.mk: (for this example, device_gt540.mk) *
PRODUCT_NAME := lg_gt540
PRODUCT_DEVICE := gt540
PRODUCT_MODEL := LG GT 540
PRODUCT_COPY_FILES += \
... specific ...
PRODUCT_PROPERTY_OVERRIDES := \
ro.com.android.dateformat=dd-MM-yyyy \
... more stuff ...
This is where all the specifics for the device such as drivers, proprietary libraries, supporting scripts specifically for the device, gets copied over to out/target/product/lg/gt540/system/ in this case. Notice how the overrides for the properties, these end up in the build.prop found in the root of the /system of the Android ROM.
BoardConfig.mk:
LOCAL_PATH:= $(call my-dir)
TARGET_NO_BOOTLOADER := true
TARGET_PREBUILT_KERNEL := device/lg/gt540/kernel
TARGET_PREBUILT_RECOVERY_KERNEL := device/lg/gt540/recovery_kernel
# This will vary from device!
TARGET_BOARD_PLATFORM := msm7k
TARGET_ARCH_VARIANT := armv6-vfp
TARGET_CPU_ABI := armeabi
TARGET_CPU_ABI := armeabi-v6l
TARGET_CPU_ABI2 := armeabi
# OpenGL drivers config file path
BOARD_EGL_CFG := device/lg/gt540/egl.cfg
# Dependant, not to be taken literally!
BOARD_GLOBAL_CFLAGS += -DHAVE_FM_RADIO
# Dependant, not to be taken literally!
BOARD_KERNEL_BASE := 0x02600000
# this will be device specific, and by doing cat /proc/mtd will give you the correct sizes
BOARD_BOOTIMAGE_PARTITION_SIZE := 0x00480000
BOARD_RECOVERYIMAGE_PARTITION_SIZE := 0x00480000
BOARD_SYSTEMIMAGE_PARTITION_SIZE := 0x0cf80000
BOARD_USERDATAIMAGE_PARTITION_SIZE := 0x0d020000
BOARD_FLASH_BLOCK_SIZE := 131072
That is an excerpt, notice how we specify kernel's base address, this is how the boot.img gets generated after compilation is done and yet again, gets dropped into out/target/product/lg/gt540/boot.img. Also, more importantly, we're telling the build system to use the target platform for cross-compiling the sources (*TARGET_BOARD_PLATFORM*/*TARGET_CPU_ABI*) There will be more information in there such as conditional flags to pass to the compiler, for an example. we specified the directive HAVE_FM_RADIO to tell it, when it comes to handling the source for the FM radio system, to conditionally compile parts of the source. Again, this is hardware specific and mileage will vary, also this applies to the address for boot. In a nutshell, this is saying 'Yo Builder, read the damn variables and remember them and apply them when cross-compiling those source files!'
Now that the internals of each of those Android build make-files are shown.
Now, onto the vendor/ part of it, in AOSP, simply, once again, correlation and corresponds with the device/ tree, as in continuing with this example, vendor/lg/gt540/ which gets picked up by the lunch. There's more make files in there but the general consensus is there's a directory called proprietary which contains the proprietary libs (due to close-source etc) that gets copied over. The copying over of the libraries gets specified in the file device-vendor-blobs.mk, in this case, gt540-vendor-blobs.mk.
When the magic happens by doing the following:
. build/envsetup.sh
This is reading in the entire entries found in each of the device/ subdirectories and "remembers them", so the build system knows what type of target is used etc.
When the . lunch gets invoked, a menu appears prompting to pick the device that is required to build. Now the last and final step to do the build...
make -j5 > buildlog.log 2>&1
I run multitail on another terminal and monitor the buildlog.log file to check and make sure its building.
This last step will depend on how many cores you have (n cores + 1 as a rule) and it takes a while to build, GB build takes 40mins on my laptop running Arch Linux 64bit, ICS build takes about 2hrs 30 mins. So mileage will vary on what type of horsepower your machine has.
When the build is done, a little bell goes off and at the bottom of the said log file, I see this:
Combining NOTICE files: out/target/product/xxxxx/obj/NOTICE.html
Target system fs image: out/target/product/xxxxx/obj/PACKAGING/systemimage_intermediates/system.img
Install system fs image: out/target/product/xxxxx/system.img
out/target/product/xxxx/system.img+ total size is 108776448
As matter of interest JBQ (Jean Baptiste Queru - the 'boss' for managing/distributing the source from Google), his build step is this...
make -j32
Yup! 32 cores! That..... is pretty powerful.
There is some information here: http://elinux.org/Android_Device
An excellent resource for anyone building Android for a device is here:
http://com.odroid.com/sigong/nf_file_board/nfile_board_view.php?bid=98
(A Practical Real-World Approach To Android Platform Development In ODROID)
Though some of the stuff in there is particular to the ODROID board, it still offers great insight into the inner workings of Android and the necessary customization for a new board.
If you're looking to get into the hardware side of things probably the single most informative resource I've found has been:
http://source.android.com/compatibility/overview.html
Read through the documentation they wrote for manufacturers looking to build android devices, it's the most thorough/complete reference you will find.

Android NDK assert.h problems

First one - is what NDEBUG somehow already defined by default, so asserts don't work until you #undef it.
Second one - they do they work, but i receive no logging in DDMS.
If there is some android specific one assert.h?
Or i just do something wrong?
If you want to compile your code with asserts then you can do it in three ways:
use NDK_DEBUG=1 argument in ndk-build commandline
add android:debuggable="true" to < application > tag in AndroidManifest.xml
add APP_OPTIM := debug to your Application.mk file - this will also disable optimizations and will compile with debug symbols
Usually program will crash due to SIGSEGV signal after assert() is called, by default NDEBUG is define, you may turn off by add the flag (LOCAL_CFLAGS += -UNDEBUG) during compilation but not work for my case.
I found another solution is using __android_log_assert, simply define as below and replace assert() with assert3:
#define assert3(e...) __android_log_assert(e, "TAG", #e)

Eclipse: Problems with JNI code debugging

Background
I'm writing application for android, using Eclipse in Windows. I'm implementing C code in JAVA and for that I'm using JNI. I have many functions and my problem is that I want to debug functions in JNI.
Question
Can I debug my code which is written in JNI in C language ?
Here is answer How to start logging for Android NDK !
Some weeks I was researching how I can write logs in Eclipse from Android NDK code. I found some examples in Internet and want to share it with you. Following steps below you can start logging on Eclipse.
Include log.h file into your Android NDK source file
#include <android/log.h>
Add the line below to your Android.mk make file.
LOCAL_LDLIBS := -llog
Now you can start logging, this two steps allows you to write logs in Eclipse from Android NDK. Write the line below in your Android NDK code and the log will bw appear in the Eclipse
__android_log_write(ANDROID_LOG_ERROR,"Tag","Message");
use following Flags to write logs in the column which you want.
typedef enum android_LogPriority {
ANDROID_LOG_UNKNOWN = 0,
ANDROID_LOG_DEFAULT, /* only for SetMinPriority() */
ANDROID_LOG_VERBOSE,
ANDROID_LOG_DEBUG,
ANDROID_LOG_INFO,
ANDROID_LOG_WARN,
ANDROID_LOG_ERROR,
ANDROID_LOG_FATAL,
ANDROID_LOG_SILENT, /* only for SetMinPriority(); must be last */
} android_LogPriority
For example if you want to write in Info column you must write
__android_log_write(ANDROID_LOG_INFO,"Tag","Message");
So, Good Luck !

Categories

Resources