I'm developping a android's aplication using some shared
libraries written by me and compiled with ndk-r5b. The application works,
y and the calls to the libraries works too, but I detected some errors,
segmentations faults, and I need to debug it, but, I don't know how debug
native code from android and I don't know if I can generate core dumps,
as in linux, for debug my libraries.
Any idea?
The ndk comes with ndk-gdb, which supposedly allows you to debug native applications. Also, if you download the whole andriod open source project, they also have some version of gdb used for debugging. Look in the docs/ folder of the ndk to learn about using it. This tutorial might also prove helpful: http://vilimpoc.org/blog/2010/09/23/hello-gdbserver-a-debuggable-jni-example-for-android/
However, as shown in a recent question I asked: Running ndk-gdb with package not found error on motorola phone I still can't get it to work.
Edit: You said in the comments you were using a Samsung Device: Samsung decide to wreck havoc on some of the crucial internals required for native debugging, but it's easily fixable if you have root access to the device. If you use the --verbose flag, you'll probably find that the error is different than that, a package unknown error. That's because it's looking in /data/system/packages.list, but samsung renamed that file to /dbdata/system/packages.list. So if you make a symlink to that file in /data/system/packages.list, (requires root access) it should work. Or at least so claims the ndk mailing list: http://osdir.com/ml/android-ndk/2011-03/msg00036.html
Related
The NDK has the ability to enable the address sanitizer on anything you build with it by adding the -fsanitize=address flag to both LOCAL_CFLAGS and LOCAL_LDFLAGS, which is nice. Well, it would be nice if it actually worked. If you add that flag and try building your library, you get a bunch of "undefined symbol" errors. You can ignore these errors by passing -Wl,--unresolved-symbols=ignore to the linker and the build completes successfully, but of course the adventure doesn't end here.
The Google's guide then says that you need a rooted device on which you run a script that modifies the runtime executable on the system partition so it loads the ASan library, and then the aforementioned missing symbols link at runtime. I tried this, and the main problem with this approach is that it also profiles something in the JVM itself thus slowing it down so much that the app doesn't start at all or crashes somewhere inside the JVM.
I've also tried the new malloc debug on an emulator but it also debugs the entire JVM thus making it unusable. All these tools seem to be absolutely not intended for the app developers but for those who work on Android itself.
I desperately need a way to fix a memory corruption crash in my app without profiling the whole virtual machine in the process. Will ASan work if I just put its library into my apk and load it before my JNI library? Are there any other ways to debug this? How do people fix this kind of bugs on Android at all?
Making a "minimal wrapper executable" and running it on some other operating system that has proper debugging tools isn't really an option here because the way the JNI library is used depends substantially on the Java part, and even if I make one, I can't be entirely sure that this bug will reproduce.
Update: I tried the asan_device_setup script on an Oreo emulator because it didn't work at all this time on a Nexus 9 with Nougat. The log flooded with linker errors of 32-bit processes trying to load 64-bit libraries and then it froze and the only way to make it usable again was flashing the factory image. Just to be sure I didn't mess anything up, I tried it several times reflashing the factory image, then TWRP, than SuperSU, and then using the "adbd insecure" app to restart the adb daemon as root. So, I started the emulator with -writable-system and ran the script on it, it completed successfully. I then built my app with ASAN and installed it, but it crashes with java.lang.UnsatisfiedLinkError: dlopen failed: cannot locate symbol "__asan_init_v3" referenced by "/data/...full path to the shared library on launch. I tried it both with and without setprop wrap.com.app.package "asanwrapper", the result is the same.
You should probably file bugs (http://b.android.com) if you're seeing performance issues this serious. We run devices that are fully ASAN instrumented every day and those work better than you'd expect. ASAN is a roughly 2x slowdown, but running your app with ASAN should work fine.
Same goes for debug malloc (I don't remember the performance implications of debug malloc, but I thought they were less severe than ASAN).
So I've been using Qt Creator for quite sometime now, but I wanted to try out their development for Android devices (Usually use Android Studio). Main reason is because I prefer C++.
I created a simple Qt Quick application, and can't even get it to run. I made no changes to the program whatsoever. It recognized my device, and I have Android SDK, NDK, and ANT set up properly (from the Qt official page).
The error I'm getting is a pretty popular one, yet so far I've seen no solutions for it.
The error reads "mingw32-make:No rule to make target'......\Downloads\android-ndk-r13b-windows-x86_64\android-ndk-r13b\sources\cxx-stlgnu-ibstdc++\4.9\include\profile\impl\profiler_map_to_unordered_map.h', needed by 'main.obj'. Stop."
Debugging is enabled on my device, everything is set up properly, device is being recognized, yet I have NO idea why I'm getting this error.
Any help would be much appreciated. It's infuriating.
SOLVED FOR THIS PROBLEM.
When using Qt Creator, no matter what version, on a windows computer the file path is the key to this problem. The length of the path.
Extracting the NDK folder and putting that folder DIRECTLY in the C:\ drive will make this build without any problems.
Leaving it in the downloads folder makes the file path TOO long for Qt Creator, hence it wont build.
There are numerous questions like this around here, the Qt sites and the OpenCV sites, but none of them quite match my case. (And a lot are unanswered anyway.)
I'm using OpenCV for Android 2.4.6 (the prebuilt version downloadable from the official site)
to build a native App for Android (4.1.2) on a Samsung Galaxy Note 2 with Qt 5.0.1 for Android
(using QtCreator 2.7.2) on a x86_64 Linux host.
I've linked against the libraries in the ../sdk/native/libs/armeabi-v7a folder. (I haven't built OpenCV from source, I'm just using what was in the downloaded package). This includes a libopencv_androidcam.a library. (And I've also tried the libnative_camera_r4.1.1.so shared lib.)
I've also downloaded the market app "OpenCV Manager".
The sample .apks from the samples directory work on my phone, but I haven't tried to build them on my own, as I don't have a Java development environment set up.
Starting my application, which contains a cv::VideoCapture inputCapture(CV_CAM_ANDROID); statement, I get the following error and no camera input:
E/OpenCV::camera(15299): CameraWrapperConnector::connectToLib ERROR: cannot dlopen camera wrapper library
E/OpenCV::camera(15299): Native_camera returned opening error: 4
My questions:
Should this work? I have seen a lot
of bug reports, but all with older
OpenCV versions and newer/older
Android versions. Bonus points if it
has been seen working on this phone
model.
Should this work out of the box with the downloaded OpenCV Android SDK? Or do I need to build OpenCV from source with some special options? (Which ones?)
Do I need special library versions on the phone itself? Do I need to have root access to the device to make this work?
Are there any "known to be working" Andoid examples using native code instead of Java?
Thanks a lot for any help!
I'll repeat the answer I got from user #Moster at http://answers.opencv.org here:
Copy libnative_camera_r4.1.1.so from the folder
/sdk/native/libs/armeabi-v7a to your Qt project's folder
/android/libs/armeabi-v7a. Make sure you have also allowed the camera
in the android_manifest in the Qt creator. Maybe all this helps
This indeed works. While I already mentioned the camera permissions in the Manifest.xml (or rather the Qt project settings), copying the shared lib to the project directory did the trick.
Seems like it's found and linked during build, but not copied to the device from its original location.
Neither the "Copy local Qt libs to device" in the deploy settings (Qt libs only?) nor the OpenCV Manager App (only loads the right libs when called directly from the Java code?) helped before.
As you may know there are three ways to deploy a Qt application on Android :
Use Ministro service to install Qt
Deploy local Qt libraries to temporary directory
Bundle Qt libraries in APK
The first method takes about 30 seconds and it also needs to install an extra apk . Ministro.
The second takes about 1 minute for me ! And anytime I try to run the program Qt creator pushes Qt libraries to the device.
The third one makes the .apk file really big and again takes about 1 minute for me.
I think with this situation that's not reasonable to develop Android application using Qt. Is there a way to make the deploying process faster?
Almost a full year since the OP and things have not changed at all. Deployment of a 7 MB APK takes over minute and a half for a project that compiles in 5 seconds. The reason I am answering is not that the problem got resolved, but to offer an alternative solution.
I've implemented a "workaround" consisting of two applications that work in tandem - one on the PC and one on the device - I created this mostly to compile files remotely, but it turned out to be a much faster alternative for deployment as well. On the host create an application that launches compilation in a separate process, when done copy the product file over network to the device to deploy. Besides remote compilation this reduced the time to deploy to like 10 seconds, I can live with that.
(Not a complete and fully tested answer yet, but I'll update if I find out more …)
Option 1: Copy the changed libraries to a rooted device
A new build will most often result only in one changed file: your libAppName.so, the native library containing your application's code. At least in 2015, it was possible to simply copy over this library to the Android device, without having to re-build the APK package. This only works with rooted Android devices (note that all emulators are rooted by default).
Step by step, according to this blog article and updated with the paths as I found them on my device:
Run the cross-compilation step on your build host system. So just make or the equivalent in Qt Creator.
Copy the resulting libAppName.so to the rooted Android device:
adb push build/path/libAppName.so /data/app/com.example.appname/lib/arm
Restart the application on the Android device.
If that works, you might even be able to integrate it as a custom deployment step in Qt Creator.
I did not test this technique yet due to lack of a rooted device. But it should still work given that (1) rooted Android devices still allow to overwrite all files and (2) debug builds of APKs can still be installed without code signing, so overwriting a library in an APK without code signing should be possible.
Option 2: Desktop targets as a workaround
I found out by chance that Qt's multi-platform character can be used to avoid the slow Android deployment 80% of the time. You just set up another compilation target; under Qt Creator you'd add a target under "Projects → Build & Run", using a kit for "Device Type: Desktop".
Now when you want to test anything that is not Android-specific, test instead in the Desktop version. Building and starting that will only take a few seconds.
This approach is further supported by using a framework for convergent application development so that the same user interface is usable both in the desktop and mobile versions. KDE Kirigami and MauiKit are two libraries for this purpose that build on Qt. Documentation for getting started is a bit scarce, but for Kirigami I wrote an extensive README for the setup of an example application.
I have a feeling I know the answer to this question, but I figure I would see what SO had to say.
I'm hoping to create a console app that can take an .apk file and extract metadata (such as version name/version number). I'm able to use PackageManager.getPackageArchiveInfo() from my Android app just fine, but I'd need to be able to call it from the command line. However, the classes in the android.jar appear to just be stubs, so it doesn't end up working.
Does anyone know of a way to do that?
For apks for which you do not have the signing certificate, you cannot access the contents of the apk beyond seeing that the contents exist.
As you noted, the android.jar is stubs. This is because the android system relies on native code which is designed to run on ARM processors and (probably) wouldn't run on your system. So, they package stub versions of all the java code and the only way to 'run' the actual library is to be executing in a vm with a full version of the android.jar, which would be an ARM environment ( a real handset or a emulator).
There could be ways to setup a 'console' app to do this, but it would have to be communicating with an Android VM to get a working version of the android.jar. I'm guessing that might be more effort than you'd want to sink into this.
I was able to open the .apk file and view it's contents (including AndroidManifest.xml) with WinZip...
'Hope that helps...