I have a normal Java application I am running on DalvikVM after converting the byte code into dex code. I manually invoke the DalvikVM from the adb shell to execute it. To enable debugging, I explictly pass arguments to DalvikVM: "-agentlib:jdwp=transport=dt_android_adb,suspend=n,server=y"
Using DDMS I can attach put breakpoints and trace code but DDMS's memory allocation tracker doesn't work. I tried Googling and the only relevant thing I could find was this:
Because command-line applications don't include the client-side DDM
setup, features like thread monitoring and allocation tracking will
not be available in DDMS.
Source: Basic Dalvik VM Invocation
So how do I include the client-side DDM setup? Is there any special code I need to add in order to make the application DDM aware or pass extra params to Dalvik?
Related
I am learning about Android process execution, and lacking info about execution of native binaries.
Normally, ELF binary is parsed and loaded by Linux via exec syscall.
This call is still available to the native applications.
Java environment has its own exec which actually asks Zygote to run ActivityThread.main
Questions: will the native exec be able to load Java-based app?
if so, where does the Zygote hook into that process?
Will the Java exec be able to run native binary that is a statically linked ELF with just an entry point?
if so, can you point me to the system code that does that?
I'm studying Android system startup and am very interested in the zygote process. Is there anyway to debug zygote with gdb or other tools? I've tried to do it with virtual machine like VMware or qemu but failed, all google results are about kernel debugging. By debug I mean I could set breakpoint, step into, check register value, etc... with gdb just like the normal process debugging with gdb.
I post this question and after several tries. I found one way to debug daemon processes as long as it started after adbd:
Stop zygote
Gdbserver attach init process
Restart zygote
Debug its child process
Background
I'm debugging an Android application using gdb 8.3 under WSL (Windows Subsystem for Linux). When debugging my app gdb frequently catches SIGSEGV and other signals that terminate the application, in general at inconsistent points in the session. These signals do not occur when the app is run without gdb. I have good reason to believe that gdb is the source of the instabilities.
I therefore want to monitor the running gdb-app using strace, in the hope of exercising the app and seeing what system function generates the offending signal when it crashes.
The Problem
strace is unable to attach to the gdb-debugged Android application because it cannot attach to an already attached process.
Here is the gdbserver command to attach to the running process:
dreamlte:/data/local/tmp # ./gdbserver :9999 --attach 26060
Attached; pid = 26060
Listening on port 9999
Remote debugging from host 127.0.0.1
I start gdb, which attaches to the running application.
With gdb attached to the Android application, I attempt to attach strace to the application:
127|dreamlte:/data/local/tmp # ./strace -p 26060
attach: ptrace(PTRACE_ATTACH, ...): Operation not permitted
I understand the problem is that the application process cannot be attached to more than once.
Is there a way to attach strace to a running gdb-app combination?
I understand the problem is that the application process cannot be
attached to more than once.
Yes, this is the limitation of ptrace() system call, see ERRORS section in man ptrace:
EPERM The specified process cannot be traced. This could be because
the tracer has insufficient privileges (the required
capability is CAP_SYS_PTRACE); unprivileged processes cannot
trace processes that they cannot send signals to or those
running set-user-ID/set-group-ID programs, for obvious
reasons. Alternatively, the process may already be being
traced, or (on kernels before 2.6.26) be init(1) (PID 1).
I therefore want to monitor the running gdb-app using strace, in the
hope of exercising the app and seeing what system function generates
the offending signal when it crashes.
Instead, you can see backtrace when the app crashes. You will probably see some system function generating signal or something else you do not expect.
Is there a "live" memory profiler tool (similar to Instruments in XCode) for Android? Most searches for memory profiling, leads me to Memory Analyzer Tool (which is great), but I would very much appreciate a tool which can dynamically show me which classes consume (and release) memory during the life-cycle of my application, as it is executing.
Note: I am not looking for a memory profiling tool for Android (Memory Analyzer Tools works very well for me). All the methods/tools I have encountered, take a snapshot of the heap and save it to a file. I am looking for a tool which provides a live counter/update on what portion of the heap is being used by various objects, and this is updated on a second/sub-second basis. It is possible that this might not be possible with Android. However, I have not found a definite answer one way or another.
Take a look at this video here at around 35mins in they show how to profile your app, not sure if you can do it 'live' tho.
More information from this post on milk.com:
Haven't tried this since android 1.6 and not sure if you could do it live but you used to be able to generate heap data by:
Get a command shell on the device:
$ adb shell
You can verify that you're running as root with the id command. The response should look like uid=0(root) gid=0(root). If not, type su and try again. If su fails, you're out of luck.
Next, ensure the target directory exists:
# mkdir /data/misc
# chmod 777 /data/misc
Use ps or DDMS to determine the process ID of your application, then send a SIGUSR1 to the target process:
# kill -10 <pid>
The signal causes a GC, followed by the heap dump (to be completely accurate, they actually happen concurrently, but the results in the heap dump reflect the post-GC state). This can take a couple of seconds, so you have to watch for the GC log message to know when it's complete.
Next:
# ls /data/misc/heap-dump*
# exit
Use ls to check the file names, then exit to quit the device command shell.
You should see two output files, named /data/misc/heap-dump-BLAH-BLAH.hprof and .hprof-head, where BLAH is a runtime-generated value that ensures the filename is unique. Pull them off of the device and remove the device-side copy:
$ adb pull /data/misc/heap-dump-BLAH-BLAH.hprof tail.hprof
$ adb pull /data/misc/heap-dump-BLAH-BLAH.hprof-head head.hprof
$ adb shell rm /data/misc/heap-dump-BLAH-BLAH.hprof /data/misc/heap-dump-BLAH-BLAH.hprof-head
Merge them together and remove the intermediates:
$ cat head.hprof tail.hprof > dump.hprof
$ rm head.hprof tail.hprof
You now have the hprof dump in dump.hprof.
The data file format was augmented slightly from the common hprof format, and due to licensing restrictions the modified hat tool cannot be distributed. A conversion tool, hprof-conv, can be used to strip the Android-specific portions from the output. This tool was first included in 1.5, but will work with older versions of Android.
The converted output should work with any hprof data analyzer, including jhat, which is available for free in the Sun JDK, and Eclipse MAT.
I noticed that when testing plain Java classes via test classes derived from TestCase and AndroidTestCase, LogCat output disappears.
Is it possible to still capture the output of these messages? or my only recourse is to use the much more sluggish ActivityInstrumentationTestCase2<> as a base class?
I had similar issue... The point here is that the logcat view available in Eclipse does not show anything when running the project in Android Junit mode. At least, in the Android 2.1 that I was using, that's the behavior.
You can workaround this issue by checking the logcat from command line (terminal window):
# check the device name you are using
# It gives something like this:
$ ./adb devices
List of devices attached
emulator-5554 device
# open logcat of the device
$ ./adb -s emulator-5554 logcat
D/AndroidRuntime( 943):
D/AndroidRuntime( 943): >>>>>> AndroidRuntime START com.android.internal.os.RuntimeInit <<<<<<
D/AndroidRuntime( 943): CheckJNI is ON
.
.
.
Both of these statements produce log in logcat:
android.util.Log.d(TAG, "This is Log.d");
System.out.println("This is System.out.println");
Just for anyone using Android Studio. You can open the Android DDMS tool window (Cmd + 6) and turn off any filters using the dropdown box in the top right. It seems to use app:com.your.package.name as a default, which filters test output.
Simply using Log.v("MyIdentifier","MyMessage") statements seems to log everything for me, both from the Unit test classes themselves and from my Android application under test.
This info may help someone using Android jUnit for the first time:
Android jUnit testing will only actually start an activity when getActivity() is called from within a test class. If get Activity is not called you will not see the results of any of the logging calls you have written in for example onCreate or onResume. There seems to be an exception to this rule though when the Activity marked as "Main" and "Launcher" in the Android Manifest is under test.