Download Training Android Debugging

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts
no text concepts found
Transcript
Training Android Debugging
TRACE32 Online Help
TRACE32 Directory
TRACE32 Index
TRACE32 Training ............................................................................................................................

Training Android Debugging ........................................................................................................

Training Android Debugging .....................................................................................................
1
Introduction .............................................................................................................................
2
Basic terms on Android ..........................................................................................................
3
Android Components
3
VM Awareness
3
Setting up a script for Android debugging ...........................................................................
4
Capture of commands for a script
4
Linux OS Awareness setup (steps and commands)
5
Setup the Linux OS Awareness
6
Setup the symbol autoloader
7
Boot the system
7
VM Awareness setup (steps and commands)
Load the Dalvik VM symbols
7
7
Scan the MMU page table of “zygote”
8
Define symbols for the Dalvik VM Interpreter
8
Load the Dalvik awareness
9
Configure JAVA extensions for Dalvik
9
Pre-load Java class information from DeX files
Additional background information
10
11
Set Dalvik VM Interpreter internal debug status
Example Android setup script
11
12
Debugging Android .................................................................................................................
VM Dalvik Features
14
14
List Virtual Machine Threads
14
View virtual machine thread stack
14
Display the stack frame for a selected VM thread
16
Examples
18
Debug daemon from main
18
Debugging the frame buffer
19
Debugging JNI calls
20
©1989-2016 Lauterbach GmbH
Training Android Debugging
1
Training Android Debugging
Version 24-May-2016
Introduction
The focus of this training is “VM-aware debugging” of Android systems, and also includes examples for
“native” debugging.
Please refer to ”Training Linux Debugging” (training_rtos_linux.pdf) for in-depth information about
debugging Linux.
Please note that “VM-aware debugging” is still under development.
©1989-2016 Lauterbach GmbH
Training Android Debugging
2
Introduction
Basic terms on Android
Here we describe essential basics and terms related to Android and Android Debugging.
1.
Android components
2.
VM Awareness
Android Components
Android is a software stack for mobile platforms, and consists of:
1.
Linux kernel and kernel modules
2.
Native processes (executed machine code), e.g. the Linux shell “sh”, Android services, e.g. rild and
vold, and the Dalvik VM process “zygote”.
3.
Native Libraries e.g. the Dalvik VM library (libdvm.so), JNI, Binder, HAL.
4.
Java applications (apps). On Android, each Java application runs in its own Dalvik Virtual
Machine instance.
For more information about debugging the native parts of Android (bootloader, Linux kernel, kernel modules
and native processes and Libraries), please refer to ”Training Linux Debugging” (training_rtos_linux.pdf).
VM Awareness
A “Virtual Machine” is not a real machine in hardware, with a fixed instruction set, a register file, memory
controller and debug logic.
For the CPU, it is “only” an application program, operating on data that is interpreted by the application as
the instruction stream for a (non-real) “virtual” machine.
For the processor, the VM “program code” is just data.
To find out which program currently runs in the virtual machine and which values its variables and objects
have, the debugger first needs to read memory content of the real machine. Then the debugger must find,
analyze and interpret the data structures of the virtual machine itself. Thus the debugger needs to “know”
the virtual machine structure; it needs to be “aware” of the virtual machine.
Additionally, for debugging, Virtual Machines are a “moving target” problem. Unlike “real hardware”, they can
- and will - be changed and implemented differently by different people, depending on current platform and
market requirements. The Dalvik Virtual Machine (DVM) is no exception. This made it necessary to
implement Dalvik VM Awareness as a TRACE32 Extension, so that it can be easily adapted - e.g. by a
customer or third party - to a concrete DVM platform and/or implementation.
©1989-2016 Lauterbach GmbH
Training Android Debugging
3
Basic terms on Android
Setting up a script for Android debugging
This chapter covers the typical steps to configure TRACE32 for convenient Android Debugging. The
demonstration target for our explanation is the PandaBoard ES2.1 with an OMAP4430 (dual Cortex-A9)
SoC.
The following pages will show the setup by now step by step:
1.
Capture of commands to later use them in a script
2.
Linux OS Awareness setup (steps and commands)
3.
VM Awareness setup (steps and commands)
4.
Sample Android setup script
Capture of commands for a script
Often it is useful to record the commands issued and the settings made in the graphical user interface (GUI)
right from the start of a TRACE32 session. For this, first you should open a LOG file:
LOG.OPEN <file>
Create and open a file for the commands to be logged. The default
extension for LOG-files is (.log)
LOG.CLOSE
Close the LOG-file
A log file records all commands - until you close it - that you execute in TRACE32, even menu selections and
relevant mouse-clicks.
In contrast, the ClipSTORE and STORE <file> commands save only specified parameters (e.g SYStem
settings) that you can reload later by executing the automatically generated script file.
STOre <file> SYStem
Create a PRACTICE batch file to restore the SYStem settings
ClipSTOre SYStem
Copy the commands to restore the SYStem settings into the
clipboard
The HISTory command only records the commands from the command line. But it offers a quick access to
the commands which were already issued during your current session. Use the cursor-up key or the mouse
to select commands from the HISTory list.
HISTory.type
Display the command history
©1989-2016 Lauterbach GmbH
Training Android Debugging
4
Setting up a script for Android debugging
Linux OS Awareness setup (steps and commands)
As already mentioned, Android is based on the Linux kernel. Debugging the native part of Android does not
differ from pure Linux debugging. This training will shortly explain the steps for Linux setup in TRACE32. You
can find more in-depth information in “Training Linux Debugging” (training_rtos_linux.pdf).
Debugger reset and setup
If you restart debugging during a debug session, you can not be sure the state of the debugger is exactly
what you want. To make sure you have a sound foundation for further debugging, use the RESet command
- for a complete session restart -, or the specific reset commands for each individual debugger function.
After this you need to setup the debugger to connect to the target platform. This includes e.g. selecting the
appropriate CPU, setting the JTAG clock to a suitable frequency, and selecting target-specific debugger
options. Also options related to Linux debugging have to be enabled, e.g. the address space needs to be
extended to support Linux tasks.
Finally, you need to connect the debugger to the target with SYStem.Up or SYStem.Mode Attach.
Load the Linux kernel symbols
The file “vmlinux” contains the Linux kernel's debug information. This file needs to be compiled with
“debugging information enabled”. You can load the kernel symbols with:
Data.LOAD.Elf vmlinux /NoCODE
; load only kernel debug symbols
With the /NOCODE option, you only load the kernel symbols into the debugger, but do not write any kernel
binary code into your target.
Setup the debugger’s MMU translation
The debugger needs to have some information about the format of the Memory Management Unit (MMU)
tables used by the kernel for address translation. For this you use the command MMU.FORMAT
MMU.FORMAT LINUXSWAP3 swapper_pg_dir 0xc0000000--0xefffffff 0x80000000
The first argument of this command can be for example “LINUX”, “LINUXSWAP” or “LINUXSWAP3” , and
describes the MMU table format. Because the Linux OS Awareness is constantly improved and extended,
please check ”RTOS Debugger for Linux - Stop Mode” (rtos_linux_stop.pdf) for the format specifiers that
©1989-2016 Lauterbach GmbH
Training Android Debugging
5
Setting up a script for Android debugging
are currently available for your platform. The second argument is the name of the kernel symbol for the
“kernel page table”. On Linux this is “swapper_pg_dir”. The third parameter is a mapping of virtual kernel
addresses to physical kernel addresses.
If you get the error message “invalid combination” after issuing the
MMU.FORMAT command, please check if you have MMUSPACES enabled.
Now you need to set the common address range with the command TRANSlation.COMMON. This is
actually the common address range for all processes and includes the kernel range as well as the virtual
machine range:
TRANSlation.COMMON 0xC0000000--0xFFFFFFFF 0x80000000--0xB00FFFFF
You can specify up to two ranges for the COMMON area using “||” in the TRANSlation.COMMON
command, or multiple ranges with additional TRANSlation.COMMON.ADD
TRANSlation.COMMON
0xC0000000--0xFFFFFFFF
TRANSlation.COMMON.ADD 0x80000000--0xB00FFFFF
Finally you need to enable the MMU table walk with TRANSlation.TableWalk ON and enable the debugger
address translation with the command TRANSlation.ON.
TRANSlation.TableWalk ON
TRANSlation.ON
If the table walk is enabled, when the debugger needs to access a virtual address which has no mapping in
the debugger's local address translation list, the debugger tries to access the kernel MMU tables to get the
corresponding physical address.
Therefore, with table walk enabled, it is not necessary to “scan” the whole MMU (with M MU.SCAN) before
the access.
Setup the Linux OS Awareness
The TRACE32 Linux OS Awareness is implemented in the file linux.t32. This is how to load the Linux OS
Awareness and its menu:
TASK.CONFIG ~~/demo/<arch>/kernel/linux/linux.t32 ; load the awareness
MENU.ReProgram ~~/demo/<arch>/kernel/linux/linux.men ; load Linux menu
©1989-2016 Lauterbach GmbH
Training Android Debugging
6
Setting up a script for Android debugging
Setup the symbol autoloader
You can specify a PRACTICE script that is called by TRACE32 whenever a process, kernel module or library
is loaded the first time, to load the corresponding symbols. This script, “autoload.cmm” is provided on your
Lauterbach DVD or installation directory in “\demo\<arch>\kernel\linux\“.
This is the command to setup the autoloader script:
sYmbol.AutoLoad.CHECKLINUX "do ~~/demo/<arch>/kernel/linux/autoload "
Note: Do not erase the blank space behind “autoload ”!
Boot the system
Everything is set up now. If Android is not already running and if you are not interested in debugging the
kernel boot, you can let Android run as long as it needs to boot completely (e.g. 60 seconds).
Go
WAIT 60.s
Break
VM Awareness setup (steps and commands)
The following setup steps are necessary for VM-aware debugging:
Load the Dalvik VM symbols
You need to load the symbols of the Dalvik virtual machine (libdvm.so).
Android 2.x used a fixed address table to place common shared libraries in memory, but Android 4.x
supports "Address Space Layout Randomization" (ASLR). This means, the load address of libraries (shared
objects) is not fixed anymore, but changes with every boot.
©1989-2016 Lauterbach GmbH
Training Android Debugging
7
Setting up a script for Android debugging
Therefore the easiest way to load the symbols - with the correct address information - is to use the
"autoloader" script:
; Enable the autoloader for processes:
TASK.sYmbol.Option Autoload PROCESS
; Enable the autoloader for the libraries of the process zygote:
TASK.sYmbol.Option Autoload PROCLIB "zygote"
; Check now:
sYmbol.AutoLoad.CHECK
; Force loading libdvm.so symbols
sYmbol.AutoLoad.TOUCH "libdvm.so"
You can also load the symbols manually, but for this you need to know the address offset of libdvm.so:
Data.LOAD.Elf libdvm.so 0x0:0x80200000 /NoCODE /NoClear
Please note that the symbols are loaded with space id 0x0, so they are visible from all processes (space id 0
is the marker for a "common" memory area in Linux).
Scan the MMU page table of “zygote”
When TRANSlation.TableWalk is enabled, it is not necessary to scan the kernel and task page tables with
MMU.SCAN.
Because the Dalvik VM Awareness frequently needs to access the page table of the process “zygote”,
however, doing a page table walk for each access could slow down debugging. Therefore we recommend
scanning the MMU page tables of the process “zygote” into the local translation table of the debugger:
MMU.TaskPageTable.SCAN "zygote"
Define symbols for the Dalvik VM Interpreter
Most of the time, a given Linux task that executes an instance of the Dalvik Virtual Machine to run an
Android Application will be in a "waiting" state in a native call function (mostly "object wait").
To find out which Java code actually causes the wait, the Dalvik VM Awareness needs to be able to detect if
and where the native task stack contains a stack frame for the VM interpreter loop. This stack frame will
contain the relevant registers and variables that point to the Dalvik instruction pointer and to the Dalvik (Java)
stack frame data.
To make this task - finding where on the task stack the Dalvik VM data is - you need to define a named range
symbol for the Dalvik VM Interpreter function, and several local variables using fixed names.
The awareness uses these names to identify the stack frame with the VM interpreter, and to access the
relevant Java instruction/method/frame pointer data.
©1989-2016 Lauterbach GmbH
Training Android Debugging
8
Setting up a script for Android debugging
The first versions of the Dalvik VM Awareness (dalvik.t32) used the name “dalvik_interp” for the VM
interpreter address range, and this worked well for Android 2.x.
But in Android 4.x, dalvik_mterp is already defined for an address range that is different from the whole
Dalvik VM, therefore newer versions of the awareness use the name “t32_dalvik_vm” instead.
The machine-optimized Dalvik VM Interpreter loop (only this one is currently analyzed and supported) is
made up from assembly language blocks, and the module address range they reside in can be accessed e.g. for ARMv7 - accessing the module label name “\\libdvm\InterpAsm-armv7-a-neon”..
LOCAL &funcrange &funcbeg &funcend
&funcbeg=address.offset(sYmbol.BEGIN("\\libdvm\InterpAsm-armv7-a-neon"))
&funcend=address.offset(sYmbol.BEGIN("\\libdvm\InterpAsm-armv7-a-neon"))
&funcrange="&funcbeg--&funcend"
sYmbol.CREATE.Function t32_dalvik_vm
&funcrange
sYmbol.CREATE.LocalVar t32_dalvik_vm rPC &funcrange Register r4 void*
sYmbol.CREATE.LocalVar t32_dalvik_vm rFP &funcrange Register r5 StackSaveArea*
; One local DVM symbol definition is different between Android 2.x and 4.x.
; For Android 2.x (FroYo) use:
; sYmbol.CREATE.LocalVar t32_dalvik_vm rGLUE &funcrange Register r6 InterpState*
; For Android 4.x (4.0.x Ice Cream Sandwich and 4.1.x JellyBean) use:
sYmbol.CREATE.LocalVar t32_dalvik_vm rSELF &funcrange Register r6 Thread*
sYmbol.CREATE.LocalVar t32_dalvik_vm rINST
&funcrange Register r7 void*
sYmbol.CREATE.LocalVar t32_dalvik_vm rIBASE &funcrange Register r8 void*
sYmbol.CREATE.Done
Load the Dalvik awareness
Now we can load the Dalvik VM Awareness extension module, and can add the Dalvik menu to TRACE32:
EXTention.LOAD dalvik.t32
MENU.ReProgram dalvik.men
Configure JAVA extensions for Dalvik
TRACE32 has built-in support for various Virtual Machines types (e.g. J2ME_CDC, KAFFE, etc.). Because
the Android APK file format is stable (thousands of rolled-out apps use this format) it was decided to
implement support for this file type directly in TRACE32. Also the Dalvik Stack Frame system on ARM is
very simple, therefore a "fallback" system for Java code stack walks was directly built into TRACE32 for it.
To use this support, however, we need to select the DALVIK mode with the Java.CONFIG command. We
also need to tell TRACE32 about the VM Interpreter address range, and the Java instruction and frame
pointers (which are stored in a local variable or register).
©1989-2016 Lauterbach GmbH
Training Android Debugging
9
Setting up a script for Android debugging
; Reset previous Java settings in the debugger
Java.RESet
; select Dalvik mode for DeXfile loader and Java symbols processing
Java.CONFIG DALVIK
; Configure Java VM interpreter routine area, ip and fp
Java.MAP.VM sYmbol.RANGE(t32_dalvik_vm)
Java.MAP.IP Register R4 sYmbol.RANGE(t32_dalvik_vm)
Java.MAP.FP Register R5 sYmbol.RANGE(t32_dalvik_vm)
Java.ON
Pre-load Java class information from DeX files
Most standard Java applications use one *.class file for each class, also extra ones for "inner classes". Also
there is a standardized mapping between a Java *.class file name and the corresponding Java package and
class names. This makes it possible to do "on-demand"-loading of Java class data: translate the Java
package name and class name to the name of the Java class file, and load it.
Android's Dalvik stores its Java class information in *.dex files (Dalvik EXecutables), which are optimized for
minimal memory footprint. To save up to 50% space (compared to uncompressed Java class files), all
Android applications only have one DeX file - classes.dex - which contains all classes that belong to this
application.
With Dalvik Applications, however, the name of the file that contains all code and debugging information is
always the same - classes.dex.
There is also no strict mapping between the APK (Android Package) file name and the Application name or
the Java package name.
So we can not even "guess" the name of the APK file that contains the classes.dex file for a specific
application or Java package.
Only by loading a classes.dex file and analyzing its contents, the debugger can derive the Java package and
class name. This is the reason why the debugger needs to "pre-load" the DeX files that are relevant for your
debug session.
This DeX file "pre-loading" is done with the Java.LOAD command e.g.:
Java.LOAD data/dalvik-cache/system@[email protected]@classes.dex
The DALVIK mode of Java.LOAD supports several file types: dex files, apk files, jar files (for framework
components from /system/framework), and odex (optimized dex) files (e.g. from the /data/dalvik-cache, or
from the /system/app directory).
©1989-2016 Lauterbach GmbH
Training Android Debugging
10
Setting up a script for Android debugging
Additional background information
On the device, the classes.dex file is “optimized” during application install (or - for a brand-new Android
device - during the very first device boot), e.g. it is pre-linked with the device's framework class libraries, then
the resulting file is stored in /data/dalvik-cache (see the preceding example). If - e.g. during an OTA (overthe-air) firmware update the Dalvik VM Interpreter or some framework classes are replaced with a newer
version, this invalidates a signature stored in the "optimized" dex file in the /data/dalvik-cache directory, and it
will be re-generated during the next boot, or latest before the next execution of the application.
Additionally, there is an Android build option to "pre-optimize" system applications ("built-in" apps from
/system/app). After pre-optimization they are stored alongside a "stripped" APK or JAR file that only contains
the remaining manifest and resources. These "pre-Optimized DEX files" have the extension *.odex, and
avoid storing two files (for the normal binary plus the dalvik-cache file). If an OTA firmware update is
performed and the Dalvik VM Interpreter is replaced with a newer version, however, all odex files need to be
updated as well during the firmware update, so they match the Dalvik VM Interpreter (and framework files)
again. Due to this fact newer Android distributions rarely use pre-optimized odex files.
Luckily - at least on ARM - there is no debug-relevant difference between DeX and ODeX files, and both can
be processed alike.
Set Dalvik VM Interpreter internal debug status
Android has an internal variable to notify the VM that a native-code debugger is attached to the system.
When this variable is set, some internal time-outs are ignored and some safeguards are disabled. You set
this variable with:
Var gDvm.nativeDebuggerActive = TRUE
©1989-2016 Lauterbach GmbH
Training Android Debugging
11
Setting up a script for Android debugging
Example Android setup script
Here is a sample PRACTICE script to set up debugging for Android 4.x (Jelly Bean) running on the
PandaBoard. The Linux kernel and the Android root file system reside on the SD card.
RESet
PRINT "initializing..."
SYStem.CPU OMAP4430
SYStem.JtagClock CTCK 30MHz
SYStem.Option DACR ON
TrOnchip.Set DABORT OFF
TrOnchip.Set PABORT OFF
TrOnchip.Set UNDEF OFF
SYStem.Option MMUSPACES ON
SYStem.Up
;
;
;
;
;
give Debugger global write permissions
used by Linux for page miss!
used by Linux for page miss!
my be used by Linux for FPU detection
enable space ids to virtual addresses
; Open a serial terminal window
DO ~~/demo/etc/terminal/term.cmm COM1 115200.
SETUP.IMASKASM ON
; lock interrupts while single stepping
; Load the Linux kernel symbols into the debugger
Data.LOAD.Elf vmlinux /GNU /NoCODE /STRIPPART 3.
PRINT "initializing debugger MMU..."
MMU.FORMAT LINUXSWAP3 swapper_pg_dir 0xc0000000--0xefffffff 0x80000000
TRANSLATION.COMMON 0x80000000--0xB00FFFFF 0xC0000000--0xFFFFFFFF
TRANSLATION.TableWalk ON
TRANSlation.ON
; Initialize Linux Awareness
PRINT "initializing multi task support..."
TASK.CONFIG ~~/demo/arm/kernel/linux/linux
MENU.ReProgram ~~/demo/arm/kernel/linux/linux
; loads Linux awareness
; loads Linux menu
sYmbol.Autoload.CHECKLINUX "do ~~/demo/arm/kernel/linux/autoload.cmm "
TASK.Option Threading TGroup ; better visibility for Dalvik threads
TASK.Option NameMode ARG0COMM ; better visibility for Dalvik threads
GROUP.Create "lib"
0x40000000--0x4FFFFFFF /YELLOW
GROUP.Create "android" 0x80000000--0xAFFFFFFF /BLUE
GROUP.Create "kernel" 0xC0000000--0xFFFFFFFF /RED
Go
WAIT 60.s ; Waiting for Android startup (60 seconds)
Break
continued on next page.
©1989-2016 Lauterbach GmbH
Training Android Debugging
12
Setting up a script for Android debugging
continued:
; Loading dalvik symbols
TASK.sYmbol.Option AutoLoad PROCESS
TASK.sYmbol.Option AutoLoad PROCLIB "zygote"
sYmbol.AutoLOAD.CHECK
sYmbol.AutoLOAD.TOUCH "libdvm.so"
; Scan dalvik MMU tables
MMU.TaskPageTable.SCAN "zygote"
; Define synthetic symbols for the Dalvik VM interpreter
LOCAL &funcrange &funcbeg &funcend
&funcbeg=address.offset(sYmbol.BEGIN("\\libdvm\InterpAsm-armv7-a-neon"))
&funcend=address.offset(sYmbol.END("\\libdvm\InterpAsm-armv7-a-neon"))
&funcrange="&funcbeg--&funcend"
sYmbol.CREATE.Function t32_dalvik_vm
&funcrange
sYmbol.CREATE.LocalVar t32_dalvik_vm rPC &funcrange Register r4 void*
sYmbol.CREATE.LocalVar t32_dalvik_vm rFP &funcrange Register r5 StackSaveArea*
; The following steps depend on your Android version:
sYmbol.CREATE.LocalVar t32_dalvik_vm rSELF &funcrange Register r6 Thread*
sYmbol.CREATE.LocalVar t32_dalvik_vm rINST &funcrange Register r7 void*
sYmbol.CREATE.LocalVar t32_dalvik_vm rIBASE &funcrange Register r8 void*
sYmbol.CREATE.Done
; Load Dalvik VM awareness
EXTension.LOAD dalvik.t32
MENU.ReProgram dalvik.men
; Configure
Java.RESet
Java.CONFIG
Java.MAP.VM
Java.MAP.IP
Java.MAP.FP
Java.ON
JAVA extensions for Dalvik
DALVIK
sYmbol.RANGE(t32_dalvik_vm)
Register R4 sYmbol.RANGE(t32_dalvik_vm)
Register R5 sYmbol.RANGE(t32_dalvik_vm)
; Pre-load DeX classes by calling a separate script
DO dex-preload.cmm
; Set internal DVM debug status
Var gDvm.nativeDebuggerActive = TRUE
; Display something
WinPOS 0. 30%
EXTension.VMList
WinPOS 0% 0%
Var.Frame /TASK "android.process.media"
WinPOS 50% 0%
Data.List /TASK "android.process.media"
Register.TASK
"android.process.media"
ENDDO
©1989-2016 Lauterbach GmbH
Training Android Debugging
13
Setting up a script for Android debugging
Debugging Android
For more information about debugging the native Android components (Boot Loader, Linux Kernel, Linux
Kernel Modules, Native Processes and Native Libraries), please refer to ”Training Linux Debugging”
(training_rtos_linux.pdf).
VM Dalvik Features
The Dalvik VM Awareness currently provides this functionality:
•
List DVM threads with their class descriptors and names.
•
Display the DVM stack for a single DVM thread.
•
List the (Java) Source code for a method/offset shown in the DVM stack view.
•
Display the stack frame for a selected DVM thread
Please also refer to the document ”VM Debugger Dalvik” (vmdalvik.pdf).
List Virtual Machine Threads
You can display a list of the Dalvik Virtual Machine (DVM) threads with the command:
EXTension.VMList
You can also open this window from the TRACE32 Dalvik menu:
View virtual machine thread stack
You can display the Dalvik VM stack for one specific DVM instance with the command EXtension.VMView
e.g.
EXTension.VMView 0xEED82400
©1989-2016 Lauterbach GmbH
Training Android Debugging
14
Debugging Android
You can also open the same window by double-clicking on the "magic" or "task name" in the
EXtension.VMView window, or by a right-click and then selecting “Display detailed”.
A double click in the column “frmCurPC” of the EXTension.VMView window opens a Data.ListJava
window. Initially this windows shows the Dalvik bytecode at the indicated position.
With a double click in the column “class descriptor”, you will load the necessary symbols from preloaded
data into TRACE32 symbol database. This then makes it possible to also display the Java source code for
the corresponding entry.
©1989-2016 Lauterbach GmbH
Training Android Debugging
15
Debugging Android
Display the stack frame for a selected VM thread
You can display the stack frame for any Linux thread with the command
Var.Frame /TASK <task_name_or_magic>
When the Java/Dalvik environment is configured correctly, this Var.Frame window will also show the
transitions between native and Java code. With Data.List /TASK <task_name> you can also display the
code for the current stack level.
Using the buttons “Up” and “Down” in the Var.Frame window, you can navigate up and down in the stack
nesting. The Data.List /TASK window will automatically switch between native code and Java depending on
the current stack level.
©1989-2016 Lauterbach GmbH
Training Android Debugging
16
Debugging Android
©1989-2016 Lauterbach GmbH
Training Android Debugging
17
Debugging Android
Examples
Debug daemon from main
You can e.g. debug the volume daemon vold from its main function. For this, you need to stop your system
before vold has been started. Then select in the “Linux” menu “”Process Debugging” -> “Debug Process on
main ...” and enter “vold” as “process name”:
As soon as “vold” is started, the autoloader loads the process symbols, and the target halts at the main()
function.
©1989-2016 Lauterbach GmbH
Training Android Debugging
18
Debugging Android
Debugging the frame buffer
You can display the current screen image from the frame buffer in TRACE32. The registered frame buffers
are listed in the array registered_fb
Each entry is a pointer to an fb_info structure. You can e.g. display the structure pointed by the first entry
in registered_fb with the command
Var.View %m %s (struct fb_info)*registered_fb[0]
Using the screen_base and the information from the var structure, you can display the frame buffer image
by the Data.IMAGE command:
In our example, the frame buffer only contains the text “A N D R O I D”. The reason for this is that on our
PandaBoard test platform, Android 4.x does not use the normal frame buffer device (/dev/graphics/fb0), but
an embedded graphics accelerator instead.
However, Android 4.x comes with a “screencap” application to make a capture of the screen. Debugging this
application gives us access to a capture of the screen. For this, we first run screencap, with a breakpoint set
near the end of the main function.
©1989-2016 Lauterbach GmbH
Training Android Debugging
19
Debugging Android
When the system stops, we can access the dimensions and image data of the screen capture via the local
variables “base”, “w” and “h”, and use them to display the screen image:
Debugging JNI calls
In this example we will debug JNI calls for the Dalvik application “android.process.acore”.
First we set a "task specific breakpoint" for the libdvm function dvmCallJNIMethod:
Break.Set dvmCallJNIMethod /TASK "android.process.acore"
©1989-2016 Lauterbach GmbH
Training Android Debugging
20
Debugging Android
Then we configure the autoloader to load any required library symbols for this process:
TASK.sYmbol.Option AutoLOAD PROCLIB "android.process.acore"
sYmbol.AutoLOAD.CHECK
When a JNI call is executed for this application, the debugger will now stop at dvmCallJNIMethod. The
parameter “method” tells us about the JNI function is about to be executed here:
After some single stepping, we will get to the native part of the JNI function:
The Frame window will now display the stack frame with the transition from Java to native code:
©1989-2016 Lauterbach GmbH
Training Android Debugging
21
Debugging Android