Simple android binary crashing with zlib - android

I made a simple android executable with CMake that links with the native zlib on the ndk. Everything compiles correctly, but when calling deflateInit I get a segmentation fault.
Here is the code:
main.cpp
#include <iostream>
#include <zlib.h>
int main()
{
z_stream strm;
deflateInit(&strm, Z_DEFAULT_COMPRESSION);
std::cout << "it works!" << std::endl;
}
And the corresponding CMakeLists.txt
cmake_minimum_required(VERSION 3.8)
project(zlib-on-android)
add_executable(main main.cpp)
find_package(ZLIB REQUIRED)
set_target_properties(main
PROPERTIES POSITION_INDEPENDENT_CODE ON)
target_link_libraries(main PUBLIC ZLIB::ZLIB)
I then compile with the following command:
cmake -H. -Bbuild -DCMAKE_SYSTEM_NAME=Android -DCMAKE_ANDROID_NDK=~/android-ndk-r17b -DCMAKE_ANDROID_STL_TYPE=c++_static -DCMAKE_SYSTEM_VERSION=16 -DCMAKE_ANDROID_NDK_TOOLCHAIN_VERSION=clang
Everything works fine. Then I do the following:
cd build
adb push main /data/local/tmp/.
adb shell
shell#device:/ $ cd /data/local/tmp
shell#device:/ $ ./main
[1] + Stopped (signal) ./main
Does anyone know the reason? I am having a lot of trouble trying to hook up gdb with this executable. Since the same code works on my Macosx, I cannot understand why it does not work on android.
EDIT
For some reason the same code crashes on Macosx (the one that worked was a similar code). This is the error: bus error ./main

Well, turns out that setting z_stream to zero fixes the problem.
#include <iostream>
#include <zlib.h>
#include <cstdlib>
int main()
{
z_stream strm;
std::memset(&strm, 0, sizeof(z_stream));
deflateInit(&strm, Z_DEFAULT_COMPRESSION);
std::cout << "it works!" << std::endl;
}

Related

How to use ndk-gdb debug executable ELF without AndroidManifest.xml on android?

I used cmake & ndk build below hello.cpp and run it on android.
#include <stdio.h>
int main() {
printf("Hello World!\n");
return 0;
}
Follow the gdb instruction. run gdbserver :1234 hello on android device.
When run $NDK/ndk-gdb on macOS encounter error msg ERROR: Could not find AndroidManifest.xml in current directory or a parent directory. Launch this script from inside a project, or use --project=<path>.
How to debug native c++ project without AndroidManifest.xml on android platform?

Why is it tough to find a dummy .so file online?

I need a dummy .so file in order to call it's functions in android. The dummy .so file could be anything from doing addition, subtraction, etc.
When searched online, All I find is "What is .so file?", "How to integrate .so file in android". Can anyone please share a dummy .so file for doing addition?
It's my first shared library, and it was quie easy to do. I've applied this toutorial.
Here is my code:
lib.h
#pragma once
int sum(const int a, const int b);
lib.cpp
#include "lib.h"
int sum(const int a, const int b)
{
return a+b;
}
main.cpp
#include "lib.h"
#include <iostream>
int main()
{
std::cout << sum(10, 20) << std::endl;
return 0;
}
and with theese commands i've vreated one:
# generating simple library
c++ -c -Wall -Werror -fPIC lib.cpp
# making it shared
c++ -shared -o libsum.so lib.o
Now you will have shared library, for making this program work i have to do 2 additional commands:
# create executable
g++ -L. main.cpp -l:libsum.so -o main
# if you try to run this command it will fail
./main
# so i've set ld path, but in the link above there are alternative solutions to that
export LD_LIBRARY_PATH=$PWD:$LD_LIBRARY_PATH
# now it should work, in my case output is: 30
./main

Linking to a shared object library (.so) when cross-compiling

I am trying to link my c-program to a shared object library (libfoo.so) using the ARM cross-compiler arm-linux-gnueabi-gcc. I am compiling on a Ubuntu system, and I want to run the program on an Android device. The compiling works, but when I try to run the program on my android device I get an error.
I've created a simple test program containing the following files:
foo.c:
#include <stdio.h>
void foo(void){ puts("Hello, I am a shared library"); }
foo.h:
#ifndef foo_h__
#define foo_h__
extern void foo(void);
#endif
main.c:
#include <stdio.h>
#include "foo.h"
int main(void)
{
puts("This is a shared library test...");
foo();
return 0;
}
I have then created the shared object library using:
arm-linux-gnueabi-gcc -c -fPIC foo.c
arm-linux-gnueabi-gcc -shared -o libfoo.so foo.o
I then compile my program using:
arm-linux-gnueabi-gcc -L/home/foo -o test main.c -lfoo
After uploading the test-program to the Android device using adb, I am not able to run it. Instead I get the error: /system/bin/sh: ./test: No such file or directory
I am in the right directory and the test-file is present, so I assume that it is the shared library that cannot be found. I've tried uploading libfoo.so to the android device as well (to the same path as specified when compiling), but it still doesn't work to run the program.
I've gotten it to work with a static library (foo.o) using arm-linux-gnueabi-gcc -static -o test main.c foo.o, but not with a shared library.
How do I properly link a shared library when cross-compiling, to make sure that the program can then run on an Android device?
The linker isn't able to dynamically link to the library.
Define LD_LIBRARY_PATH environment variable to include the library:
export LD_LIBRARY_PATH=/home/foo

Calling function from .so file created in android in linux C++ code

I have .so file which I take from apk. With command nm -D libnative-lib.so I took list of functions. I need to call function named Java_com_example_nativelib_utils_Constants_getStringFromJNI . I wrote the code below:
#include <stddef.h>
#include <dlfcn.h>
#include <stdio.h>
int init_library() {
void* hdl = dlopen("./libnative-lib.so", RTLD_LAZY);
if(hdl == 0)
return 0;
else return 1;
}
int main() {
printf("%s\n", (init_library() ? "OK": "ERROR"));
}
and make file:
all: exe
exe: main.c
gcc main.c -fPIC -ldl -o main
but result of program is always "ERROR". I tried libnative-lib.so from x86 and armeabi-v7a architectures (others not present). How to load library and call function from it? C++ or C do not care.
It is not possible to use android .so files in non-android project. similar question is here

C++ code on Android - execl() function call failure

The Story - I got a script file on a rooted Android Wear device and I want to run it with my c++ code.
First I tried this int ret = system(/system/bin/sh /full/path/a.sh), it turned out that every time system() return with code 127 - command not exists error.
I found this workaround here: system is returning error 127 when called from c++ in linux and I do as #Nikhilendra said:
int ret = execl("/system/bin/sh","/system/bin/sh","/full/path/a.sh",(char*)NULL)
Now my c++ code crash at this line every time, even without return value, so I cant get any error code on this.
Any help is highly appreciated.
EDIT1:
The script a.sh itself runs correctly.
EDIT2:
My question can be understood as a follow-up of system is returning error 127 when called from c++ in linux
If you want to use one of the exec functions to mimic the system call, you have to fork a new child process first because the current process (image) is replaced by the one given in the exec call. That is, the exec will only return, if it failed.
I can't say, if the fork system call works on Android. But, you can check the exec call with this little example. I actually tested it on a Linux machine. EDIT: You may have to change the path of sh to /system/bin/sh.
The content of a.sh:
#!/bin/sh
echo "Hello World."
The content of the C++ test program (called it exec_test).
extern "C" {
#include <unistd.h>
#include <errno.h>
}
#include <iostream>
int main()
{
execl("/bin/sh","sh","./a.sh",NULL);
// execl only returns if it failed
std::cout << "errno: " << errno << std::endl;
return 0;
}
The output:
$ ./exec_test
Hello World.

Categories

Resources