Trouble with undefined reference to Callstack library - android

I try to build a cpp file as below to an executable on the Android platform. Therefore, by calling dumping_callstack(), I can get call stack of my executable in run time. But there are some errors。
cpp file:mycallstack.cpp
#include <utils/CallStack.h>
extern "C" void dumping_callstack()
{
CallStack stack("haha");
}
mycallstack.h
void dumping_callstack();
test.c
#include <mycallstack.h>
main()
{
dumping_callstack();
}
android.mk
LOCAL_SRC_FILES += mycallstack.cpp
LOCAL_SHARED_LIBRARIES := libc libcutils liblog libutils
then compile.
error: undefined reference to 'android::CallStack::CallStack(char const*,int)'
error: undefined reference to 'android::CallStack::~CallStack()'

In android 9.0, you should use libutilscallstack.
Look "android/system/core/libutils/Android.bp" for more details.

The implementation of CallStack::CallStack and CallStack::~CallStack isn't provided to the compiler/linker.
You might forgot to link it to the corresponding object file/library, I suggest you to read the documentation, there might be some information about linking. Sometimes it can help to just compile it with the -static switch, this makes the executable almost standalone, some libraries even require to be linked staticly.
It might also be the case, that the implementation is not available for release builds, I think the CallStack-class could only be available for debugging.

Related

about mangled name of functions in c++

ı have closed source shared library that links against libmedia.so from android
but unforunatly in >android 5.0 ABI changes that made by google broke my closed source lib (thanx google)
now ı have the following error --> dlopen failed cannot locate symbol "_ZN7android11MediaPlayer13setDataSourceEPKcPKNS_11KeyedVectorINS_7String8ES4_EE" referenced by "mylib.so"
then ı hexedited my closed source library(mylib.so) to load myhack.so (that ı built myself) instead of libmedia.so (so ı simply made a trick)
here is the Android.mk of myhack.so library:
include $(CLEAR_VARS)
LOCAL_SRC_FILES := hack.cpp
LOCAL_SHARED_LIBRARIES := libmedia
LOCAL_MODULE := myhack
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := SHARED_LIBRARIES
include $(BUILD_SHARED_LIBRARY)
and here is the hack.cpp:
extern "C" void _ZN7android11MediaPlayer13setDataSourceERKNS_2spINS_17IMediaHTTPServiceEEEPKcPKNS_11KeyedVectorINS_7String8ES9_EE();
extern "C" void _ZN7android11MediaPlayer13setDataSourceEPKcPKNS_11KeyedVectorINS_7String8ES4_EE() {
return _ZN7android11MediaPlayer13setDataSourceERKNS_2spINS_17IMediaHTTPServiceEEEPKcPKNS_11KeyedVectorINS_7String8ES9_EE();
}
let me explain a bit:
1-as I said I hexedited my closed source lib to load myhack.so instead of libmedia.so (source file and android.mk file of myhack.so are in above)
2-I linked myhack.so to libmedia.so(as you can see) to provide other libmedia functions via myhack.so
LOCAL_SHARED_LIBRARIES := libmedia
3-
lost symbol: _ZN7android11MediaPlayer13setDataSourceEPKcPKNS_11KeyedVectorINS_7String8ES4_EE
current symbol in libmedia.so: _ZN7android11MediaPlayer13setDataSourceERKNS_2spINS_17IMediaHTTPServiceEEEPKcPKNS_11KeyedVectorINS_7String8ES9_EE
so if lost symbol is called, it will return original function
my question is should I use extern "C" void or extern "C" int..... int or void? which one? setDataSource is a function and I dont think it is returning integer value so it should be void ı think but ım not %100 sure
could anyone help me please? thanx
Sooner or later you will get in troble with it. I remember problems with skia on project I work on. Some vendors were doing small changes with interfaces and that was causing various crashes.
To find return type you can investigate sources for android, steps are below:
You can use https://demangler.com/, to see signature of your function, it should be:
android::MediaPlayer::setDataSource(android::sp<android::IMediaHTTPService> const&, char const*, android::KeyedVector<android::String8, android::String8> const*)
now lets search android sources for such signature, you can find it here:
http://androidxref.com/6.0.1_r10/xref/frameworks/av/media/libmedia/mediaplayer.cpp#148
so its return type is status_t, which is typedef int status_t;, so as you have assumed its int.

Using opencv in native code for Android app development

I have namespace error building with ndk-build for native code in my Android app. The error sample is
C:/adt-bundle-windows-x86/ndk/sources/cxx-stl/gnu-libstdc++/4.6/include/bits
/allocator.h:54:1: error: unknown type name 'namespace'
C:/adt-bundle-windows-x86/ndk/sources/cxx-stl/gnu-libstdc++/4.6/include/bits
/allocator.h:55:1: error: expected ',' or ';' before '{' token
For OpenCV settings, my Application.mk file is
APP_STL := gnustl_static
APP_CPPFLAGS := -frtti -fexceptions
APP_ABI := armeabi
APP_PLATFORM := android-10
That means I am using gnu-libstdc++ in compiling the native code.
My jni.c has c extension. That is I receive from my third party and they prefer in .c extension as if they have to change to .cpp extension, they have to change a lot in their other libraries.
So far is OK, I did all project settings for OpenCV for native development and if I do ndk-build, I can make .so libraries.
The problem of those namespace error happened when I include OpenCV's header file #include <opencv2/contrib/detection_based_tracker.hpp> into jni.c and I got a lot of name space error. If I include that #include <opencv2/contrib/detection_based_tracker.hpp> into cpp file, no error.
My questions are
(1)Is the error is because of using .hpp file in .c file?
(2)If I have no choice and have to use that .c file, is there way around to remove that error?
Thanks
My assumption would be that the file is compiled as a "C" file instead of a "C++" file because of the extension ".c". That means you cannot use any "C++" Code in your jni.c, wike classes or namespaces. These are obviously used however in your file "detection_based_tracker.hpp" that you are using.
So the problem is not that you include a file named ".hpp", but that this file contains "C++" code wich the "C" compiler cannot handle.
One solution to this problem is to only use the "C" functions in opencv (for example "opencv2/imgproc/imgproc_c.h" instead of "opencv2/imgproc/imgproc.hpp"). However, your function "detection_based_tracker.hpp" might not have a "C" version, as far as I can see.
The other option is to add a second file "function.cpp" with the "C++" functions that use opencv. The functions from "function.cpp" can be declared in a file "functions.h" and included in your "jni.c", so you can still use opencv c++ functions. Be careful to only use C style functions then, though (no classes, namespaces, ...) in your "function.h" file, otherwise you will have the same problems as before.

How to link multiple static libs in android shared lib

I have pre build boost libs for android using standalone tool chain 4.8.
I want to use he following boost libs and added as following in Android.mk
LOCAL_STATIC_LIBRARIES += libboost_atomic \
libboost_date_time \
libboost_exception \
libboost_thread \
libboost_system \
libboost_filesystem
I have adde my own static lib liblocal.a in Android.mk.
I have a mainactivity.cpp file in my JNI folder of android project.
I am including header.h in mainactivity.h. header.h had class declaration for classA which uses boost libs.
while building liblocal.a, I am not getting any link error for boost.
While inclduding header.h in mainactivity.h I am getting the following link error:
../../../3p/boost/android/include/boost/system/error_code.hpp:222: error: undefined reference to 'boost::system::generic_category()'
../../../3p/boost/android/include/boost/system/error_code.hpp:223: error: undefined reference to 'boost::system::generic_category()'
../../../3p/boost/android/include/boost/system/error_code.hpp:224: error: undefined reference to 'boost::system::system_category()'
../../../3p/boost/android/include/boost/system/error_code.hpp:222: error: undefined reference to 'boost::system::generic_category()'
../../../3p/boost/android/include/boost/system/error_code.hpp:223: error: undefined reference to 'boost::system::generic_category()'
../../../3p/boost/android/include/boost/system/error_code.hpp:224: error: undefined reference to 'boost::system::system_category()'
../../../3p/boost/android/include/boost/system/error_code.hpp:224: error: undefined reference to 'boost::system::system_category()'
Thanks,
Birajendu
If liblocal.a depends on functions defined in libboost_foo.a, then it must appear before it in the list of static libraries, i.e.:
LOCAL_STATIC_LIBRARIES += liblocal.a libboost_foo.a # GOOD
Should work, while the following:
LOCAL_STATIC_LIBRARIES += libboost_foo.a liblocal.a # BAD
will not, and result in a link error like the one you described.
A work-around is to use LOCAL_WHOLE_STATIC_LIBRARIES that always forces all content from the listed static libraries to be included in the result (this typically generates bloated binaries, but may be necessary if you have circular dependencies).
Hope this helps.
Solved:
I have added LOCAL_LDLIBS += -L$(RELATIVE_PATH_TO_LIB) -lmylib -lmylib1, this solved this issue.
Where as mylib.a and mylib1.a are my pre build static libs.

Android: error: undefined reference to 'android_atomic_dec'

I am trying to build my code for h.264 video decoding using hardware decoder(OMX codec) in native code of android 4.0.4 by keeping it in the android source tree. The android source is already built. I am using mm command to build my decoder module.
But when I try to build it I am getting the following error
prebuilt/linux-x86/toolchain/arm-linux-androideabi-4.4.x/bin/../lib/gcc/arm-linux-androideabi/4.4.3/../../../../arm-linux-androideabi/bin/ld:
out/target/product/generic/obj/SHARED_LIBRARIES/custom_decoder_intermediates/custom_decoder.o:
in function custom_decoder::decode_video():frameworks/base/include/utils/RefBase.h:171:
error: undefined reference to 'android_atomic_dec'
when I explored about it, came to know that android_atomic_dec is defined in cutils/atomic.h
which is in system/core/libcutils and the header at system/core/include/cutils of AOSP 4.0.4.
So I have added this also in my android.mk via LOCAL_C_INCLUDES but still to get the same error.
Can someone help me to solve this ??....
You must add cutils to the linkage stage:
LOCAL_LDLIBS += -L $(path-to-system-libs) -lcutils
If you are building AOSP tree, use instead the following:
LOCAL_SHARED_LIBRARIES += libcutils

Linker trouble when using LuaJIT prebuilt static library with android under cygwin

I think I spent most of yesterday unsuccessfully wrestling with this, any help would greatly appreciated and make me extremely happy! Even a next step to try to find the root of the issue is something I'm stuck on at the moment!
I have an Android 2.2 project that's trying to reference a prebuilt LuaJIT static library but ndk-build gives me this error:
test_android.cpp:25: undefined reference to `luaL_newstate'
I built LuaJIT as liblua.a, I've placed that in the root of my JNI directory with the relevant headers. I've have one Android.mk as shown below:
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := lua
LOCAL_SRC_FILES := liblua.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := test
LOCAL_CFLAGS := -Werror
LOCAL_SRC_FILES := test_android.cpp
LOCAL_LDLIBS := -llog -lGLESv2
LOCAL_STATIC_LIBRARIES := lua
include $(BUILD_SHARED_LIBRARY)
In test_andrdoid.cpp I've got this code:
extern "C"
{
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
}
void test()
{
lua_State* lua = lua_open();
}
This seems like a linker error, for some reason the static library file is not being correctly referenced. But, to me, the makefile seems correct.
Any help would be greatly appreciated!
To start with: is there anyway to see how everything is being linked
together and if my shared library module is really get access
to the static library?
Additional Information
Here's extra information that I think could be relevant!
Building the library
Maybe it's the static lib file that's not correct? (Is there anywhere I could download a prebuilt one to check?). I made it with this script (from the LuaJIT website). I'm using the latest stable LuaJIT, 1.1.8
NDK=/cygdrive/c/android-ndk-r8b
NDKABI=8
NDKVER=$NDK/toolchains/arm-linux-androideabi-4.4.3
NDKP=$NDKVER/prebuilt/linux-x86/bin/arm-linux-androideabi-
NDKF="--sysroot $NDK/platforms/android-$NDKABI/arch-arm"
make linux HOST_CC="gcc -m32" CROSS=$NDKP TARGET_FLAGS="$NDKF"
This builds fine and creates a liblua.a in the /src/ directory. (I ran nm on it and it lists out all the function prototypes I'd expect). I don't know if there's anything else I can do to ensure it's really a build for ARM?
NDKABI=8 means I'm targeting Android 2.2
Setting up the test Android Project
I create a brand new 2.2 android project using this command:
android create project --target 3 --name test --path . --activity TestActivity --package com.test
Target 3 maps to Android 2.2 on my system (using android list devices).
I create the jni folder and have a test_android.h and test_android.cpp. Then I use ndk-build to build them - which works fine when I'm not trying to reference LuaJIT. When I do try and use Lua I get the following error:
Full Error Message
Cygwin : Generating dependency file converter script
Compile++ thumb : test <= test_android.cpp
In file included from jni/test_android.h:3:0, from jni/test_android.cpp:2:
C:/android-ndk-r8b/platforms/android-8/arch-arm/usr/include/jni.h:592:13: note:
the mangling of 'va_list' has changed in GCC 4.4
Prebuilt : liblua.a <= jni/
StaticLibrary : libstdc++.a
SharedLibrary : libtest.so
obj/local/armeabi/objs/test/test_android.o: In function `test()':
C:\Users\Grrr\Documents\mycode\static_lib_test/jni/test_android.cpp:25: undefined reference to `luaL_newstate'
collect2: ld returned 1 exit status
/cygdrive/c/android-ndk-r8b/build/core/build-binary.mk:378: recipe for target `obj/local/armeabi/libtest.so' failed make: *** [obj/local/armeabi/libtest.so] Error 1
Most of the issues I've seen searching around are due to the local library include order, as I only have one library this shouldn't be an issue and suggests I've managed to get something more fundamental wrong :)
Update
I've since built normal Lua and added that as prebuilt static library and it works fine. I suspect its how I've built LuaJIT but I'm not sure how to correctly build it, or find a working prebuilt version.
The linking for this was fine, or at least the makefile was.
The problem was the LuaJIT library wasn't built for ARM (I used objdump -a lualib.a, to check this). I downloaded the latest LuaJIT, ran the script under linux and got an ARM library. Everything links nicely now!

Categories

Resources