Well, the easiest way is to use Android Studio.
Import the project in Android Studio as a gradle
project and build the project. Krita build will fail when run from Android Studio. Now, to run it successfully, we’ll have to manually provide the path to installPrefix
or comment out copyLibs
dependency. Now, the project should build properly.
You might want to change the debug type to Native
or Dual
, as their Auto
mode did not work for me. Open the C++ file in Android Studio and set a breakpoint. Click the bug icon, sit back and watch while Android Studio does all the magic for you.
And then it is usual lldb
(in Android Studio) or GUI if that’s what you prefer.
Using command line:
Starting Android studio takes a lot of time and memory. Then, it builds which takes an additional few minutes, so it really isn’t a good idea to use it for debugging every time the app crashes. So, the less time consuming one and a bit complex method – here we go!
Assuming the app has been installed with the debug key. The first step is to launch it in debug mode, to do so:
# domain/(launcher activity or exported activity's class-path)
$ adb shell am start -D -n "org.kde.krita/org.krita.android.MainActivity"
Now the app on phone should launch and show Waiting for Debugger
message. While it waits – open a terminal and enter $ adb shell
, and then look for lldb-server
in /data/local/tmp/
. If you ever debugged app through Android Studio, then it should exist. If it does not, then launch Android Studio and run it in debug mode 😂…hahahaha.
Just kidding, push the file to that location.
$ adb push $ANDROID_SDK_ROOT/lldb/<version>/android/<abi>/lldb-server /data/local/tmp
$ adb shell chmod +x /data/local/tmp/lldb-server
(No lldb
directory? See notes)
Then for us to access the libraries, we’ll have to copy it to /data/data/org.kde.krita
, for that:
$ adb shell run-as org.kde.krita cp /data/local/tmp/lldb-server /data/data/org.kde.krita
(Why run-as
? It is a setuid
program and gives us the necessary permission to access the sandbox).
Now, enter the app sandbox by first entering the $ adb shell
and then $ run-as org.kde.krita
.
Run the lldb-server
like you would if you were remote debugging.
$ ./lldb-server platform --server --listen "<incoming-ip>:<port>"
$ # Example: allow any ip on port 9999
$ ./lldb-server platform --server --listen "*:9999"
Now on the host machine, run lldb
and then
(lldb) platform select remote-android
(lldb) platform connect connect://<ip>:<port>
On my machine:
(lldb) platform select remote-android
Platform: remote-android
Connected: no
(lldb) platform connect connect://localhost:9999
Platform: remote-android
Triple: arm-*-linux-android
OS Version: 28.0.0 (4.4.153-15659493)
Kernel: #2 SMP PREEMPT Thu Apr 4 18:31:57 KST 2019
Hostname: localhost
Connected: yes
WorkingDir: /data/data/org.kde.krita
You can read more about what they do on LLVM’s website.
(This is one a time setup you can keep the server and client connected)
Remember, that our process is still Waiting for Debugger
? :(
Let’s give it what it wants. Attach the debugger to the running process’s pid, which can be known by $ adb shell ps | grep "krita"
or $ pgrep "krita"
To attach:
(lldb) attach <pid>
(lldb) # on my machine
(lldb) attach 1818
Process 1818 stopped
* thread #1, name = 'org.kde.krita', stop reason = signal SIGSTOP
frame #0: 0xe8d35f7c libc.so`syscall + 28
<and much more>
Still didn’t continue? :-<
So, let’s finally resume it!
We’ll have to resume it over Java Debug Wire Protocol (JDWP), we’ll use jdb
$ adb forward tcp:12345 jdwp:<pid> # the same pid which we attached in lldb
$ jdb -attach localhost:12345
Now continue
the process in lldb
and we are done!
(This might seem like a lot, but it really isn’t. Every time the app crashes, I run in debug mode $ attach pid
and I get the backtrace immediately!)
PS: When I was looking for it on the internet, I didn’t find much about it and had to spend a lot of time on this.
This method should work with debugging any android app with lldb
, obv!
(I am really new to blogging. If it’s hard to understand or my formatting is bad, I am really sorry.)
Notes
- I hate the extra
jdb
thing, and if the function which you want to debug is not going to be called during the early start up, you can use-N
flag instead of-D
witham
. - Can’t find
lldb
directory in your SDK? Use platform tools to install it. jdb
doesn’t attach?$ killall android-studio && adb kill-server #_#
Resources
https://source.android.com/devices/tech/debug/gdb
https://android.googlesource.com/platform/ndk/+/master/ndk-gdb.py
https://lldb.llvm.org/use/remote.html
Hi, I'm debugging an app in LLDB, but the following errors always happen.
ReplyDelete(lldb) platform select remote-android
Platform: remote-android
Connected: no
(lldb) platform connect connect://localhost:6002
Platform: remote-android
Triple: aarch64-unknown-linux-android
OS Version: 27 (3.10.73-ElementalX-N5X-6.12)
Kernel: #1 SMP PREEMPT Mon Dec 3 15:39:39 EST 2018
Hostname: localhost
Connected: yes
WorkingDir: /system/bin
(lldb) process attach --pid 543
Process 543 stopped
* thread #1, name = 'e.myapplication', stop reason = signal SIGSTOP
frame #0: 0x00000016fd40a3f8
error: memory read failed for 0x16fd40a000
thread #2, name = 'Jit thread pool', stop reason = signal SIGSTOP
frame #0: 0x00000016fd3bd4ac
error: memory read failed for 0x16fd3bd000
thread #3, name = 'Signal Catcher', stop reason = signal SIGSTOP
frame #0: 0x00000016fd40a5d8
It fails to read memory in LLDB, do you know why it failed to read memory in LLDB? Thanks!
Hello!
DeleteLooking at the addresses and the triple returned by lldb. I am guessing you are using 64 bit `lldb-server` to debug a 32 bit binary. So, I would suggest you to push the 32 bit version, which should be in `$ANDROID_SDK_ROOT/lldb//android/armeabi/lldb-server` and then try to debug it.
Hi,
ReplyDeleteThe debugged app has a 64 bit so like the following.
bullhead:/data/app/com.example.myapplication-2AqHZSk9eGrvrzCgS7aoVg==/lib/arm64 # ls
libpl_droidsonroids_gif.so
ile libpl_droidsonroids_gif.so <
libpl_droidsonroids_gif.so: ELF shared object, 64-bit LSB arm64, BuildID=264656f26f9f1ea9cacd0c71c87b9c7bf64b4124, for Android 23, built by NDK r20b (5948944), stripped
I pushed the 64 bit lldb-server into android device. My debugging device is LG Nexus 5x OS: andorid 8.1. The 0x00000016fd40a3f8 is a 64 bit memory address. lldb-server is /Users/kailu/Library/Android/sdk/lldb/3.1/android/arm64-v8a/lldb-server
The following is the version info of lldb-server.
bullhead:/data/local/tmp # lldb-server v
lldb version 6.0.0 (https://us3-mirror-partner-android.googlesource.com/a/platform/external/lldb revision a7bde94648f7d808066e16b5aefb18b5cf06bd01)
clang revision d4f31fa2ec80bbffa638d47ac9cd0997559fb215
llvm revision 1f769b41e8cf646893a50ba8d9595ef6d913ad02
bullhead:/data/local/tmp # file lldb-server
lldb-server: ELF shared object, 64-bit LSB arm64, dynamic (/system/bin/linker64), for Android 21, built by NDK r15c (4203891), BuildID=16479c73b494c432c5f171db2bb68f29e033f157, stripped
bullhead:/data/local/tmp #
Any clue for it?
I am afraid! No, I don't know what is causing this :(
DeleteI would try to use gdbserver to see if I get any different results, and then probably report it to LLVM.
wow
ReplyDelete