[펌] Android Debugging
Android Debugging
From OMAPpedia
Contents[hide] |
[edit] Eclipse ADT
[edit] Debugging on Zoom2 with Eclipse ADT
The Android Development Tools (ADT) plugin for Eclipse adds powerful extensions to the Eclipse integrated development environment. It allows you to create and debug Android applications easier and faster. Details on ADT can be obtained from http://developer.android.com/guide/developing/eclipse-adt.html.
It is assumed that ADT plugin has already been setup to work with Eclipse environment as described http://developer.android.com/sdk/1.1_r1/installing.html#installingplugin.
Step 1: Unpon installing the ADT plugin for eclipse, Dalvik Debug Monitor Service (DDMS) should have been setup. DDMS configuration should be changed as in below:
Click on Window->Preferences; Select Android -> DDMS Change - ADB debugger base port: 8700; Logging Level: Verbose Click on Apply
Step 2: DDMS perspective can now be opened from the eclipse menu via:
Window -> Open Perspective -> Other -> DDMS; Click on OK
Step 3: Get Eclipse to attach to your Zoom2 board.
Bootup the zoom2 board and find the IP address of the board. NOTE: If you boot via NFS, then uboot will typically print out the board's IP address to console. Alternatively, from the command shell this can be gathered from /system/bin/netcfg utility.
On the host machine run the following commands from terminal shell:
export ADBHOST=<IP_ADDRESS_OF_YOUR_ZOOM2_BOARD> adb kill-server adb start-server
Check if you are now connected to the Zoom2 device by running the following command on the Host Terminal console:
adb devices
It should output something like:
emulator-5554 device
This confirms that Zoom2 board is connected. With this setup, you should be able to use Android Debug Bridge, Logcat, DDMS and other tools directly from Eclipse ADT environment for creating your applications for Android on Zoom2.
Step 4: Troubleshooting:
ADB is not in the path, where should I find it?
ADB command line tool is found at: <MYDROID_PATH>/out/host/linux-x86/bin/
[edit] Debugging with GDB and DDD
The user space programs can be debugged using various debug commands). Here are some gnu apps that can be used to ease the debugging of binary files on the android platform. GDB, allows you to see what is going on `inside' another program while it executes -- or what another program was doing at the moment it crashed.
[edit] GDB (the GNU Debugger)
Following are the instructions to enable GDB on Android:
1. Obtain the IP address of the target. This can be found by adding “ip=dhcp” in the bootargs, which will obtain and print the IP automatically during boot. Alternatively if you have the busybox command line tools available on the target you can type "ifconfig eth0" to obtain the IP address of the target.
2. On the host, perform the following (once per new console window): Go to mydroid directory and run
source build/envsetup.sh setpaths export ADBHOST=<ip addr of target obtained above>
Ensure that above setup works by running
adb kill-server ; adb shell
You should see a command prompt of the target on your host. Verify this by running "ps" or similar commands. Exit the adb shell by typing “exit”
3. Start GDB using the following command
gdbclient <executable name> <port number> <task name> executable name: file name in system/bin dir port number: default is :5039 (need the colon before the number) task name: obtained by running "ps" on the target. GDB uses it to identify the PID internally.
E.g. for video playback, use (note the space after mediaserver and colon):
gdbclient mediaserver :5039 mediaserver
Then you can run commands like “info threads”, “break”, “step” etc.
For a full listing of GDB commands refer to: http://www.yolinux.com/TUTORIALS/GDB-Commands.html
You may have to run the following after each target reboot:
adb kill-server
[edit] DDD (Data Display Debugger)
DDD is a graphical front-end for GDB and other command-line debuggers like GDB.
Following are the instructions to enable DDD on Android:
The steps are almost same as GDB:
1. Obtain the IP address of the target. This can be found by adding "ip=dhcp" in the bootargs, which will obtain and print the IP automatically during boot. Alternatively if you have the busybox command line tools available on the target you can type "ifconfig eth0" to obtain the IP address of the target.
2. Install DDD: in the shell run:
sudo apt-get install ddd3
3. Add the following function to build/envsetup.sh:
function dddclient() { local OUT_ROOT=$(get_abs_build_var PRODUCT_OUT) local OUT_SYMBOLS=$(get_abs_build_var TARGET_OUT_UNSTRIPPED) local OUT_SO_SYMBOLS=$(get_abs_build_var TARGET_OUT_SHARED_LIBRARIES_UNSTRIPPED) local OUT_EXE_SYMBOLS=$(get_abs_build_var TARGET_OUT_EXECUTABLES_UNSTRIPPED) local PREBUILTS=$(get_abs_build_var ANDROID_PREBUILTS) if "$OUT_ROOT" -a "$PREBUILTS"?; then local EXE="$1" if "$EXE"? ; then EXE=$1 else EXE="app_process" fi local PORT="$2" if "$PORT"? ; then PORT=$2 else PORT=":5039" fi local PID local PROG="$3" if "$PROG"? ; then PID=`pid $3` adb forward "tcp$PORT" "tcp$PORT" adb shell gdbserver $PORT --attach $PID & sleep 2 else echo "" echo "If you haven't done so already, do this first on the device:" echo " gdbserver $PORT /system/bin/$EXE" echo " or" echo " gdbserver $PORT --attach $PID" echo "" fi echo >|"$OUT_ROOT/gdbclient.cmds" "set solib-absolute-prefix $OUT_SYMBOLS" echo >>"$OUT_ROOT/gdbclient.cmds" "set solib-search-path $OUT_SO_SYMBOLS" echo >>"$OUT_ROOT/gdbclient.cmds" "target remote $PORT" echo >>"$OUT_ROOT/gdbclient.cmds" "" ddd --debugger arm-eabi-gdb -x "$OUT_ROOT/gdbclient.cmds" "$OUT_EXE_SYMBOLS/$EXE" else echo "Unable to determine build system output dir." fi }
4. On the host, perform the following (once per new console window): Go to mydroid directory and run
source build/envsetup.sh setpaths export ADBHOST=<ip addr of target obtained above>
Ensure that above setup works by running
adb kill-server ; adb shell
You should see a command prompt of the target on your host. Verify this by running "ps" or similar commands. Exit the adb shell by typing “exit”
5. Start DDD using the following command
dddclient <executable name> <port number> <task name> executable name: file name in system/bin dir port number: default is :5039 (need the colon before the number) task name: obtained by running "ps" on the target. GDB uses it to identify the PID internally.
E.g. for video playback, use (note the space after mediaserver and colon):
dddclient mediaserver :5039 mediaserver
For the DDD manual, refer to: http://www.gnu.org/manual/ddd/html_mono/ddd.html
You may have to run the following after each target reboot:
adb kill-server
[edit] Lauterbach Trace32
Lauterbach could be used to debug bootloaders, kernel and user space. Instructions on using Lauterbach Trace32 for debugging on Zoom2:
Install Lauterbach Trace 32 software on your PC (the below screenshot is from Oct 10 2008 release). Connect emulator cable to J5 (20 pin header) on Zoom2 debug board and power the emulator. Connect USB cable from the emulator to PC
Run zoom2_startup.cmm script to select your target as OMAP3430 and attach from File -> Run Batchfile. If the script is not run, some of the settings will have to be manually selected from CPU -> System Settings
Ensure that the emulator is “running” by the green status indicator (seen at the bottom of the below screenshot) before exercising any use cases that need to be debugged.
Run the use case (ex: audio/video playback) Halt the processor by clicking on the “pause” button and view registers (View -> Registers), list source (View -> List Source) etc.
Make sure to load the symbols for files that you’re interested in debugging and set source path recursively for source code correlation to work correctly. Also you may have to ensure that options such as –g is added during compiling your code to generate symbolic debugging directives. In some instances consider reducing the level of optimization used as the compiler will re-arrange instructions and hence it may be difficult to match the order of execution in the source code.
Examples of setting the source search path and loading symbols:
symbol.SOURCEPATH.SETRECURSEDIR "V:\mydroid\kernel\" data.load.elf V:\mydroid\kernel\vmlinux /nocode
These commands can be directly entered from either the debugger command prompt or by using a *.cmm script.
For user space debugging, T32 needs some help as it needs to be told where some of the modules you're interested in debugging are loaded. To do this you will have to run "ps" on the target and get PIDs for the application.
Then run "cat /proc/PID/maps > logfile" where PID is the process ID retrieved from "ps" in the above step. There is an avplayback_symbols.cmm file attached that exhibits how to do this. Below screenshot demonstrates being halted in user space during running of an AV playback use case.
zoom2_startup.cmm
avplayback_symbols.cmm
[edit] CodeComposer
This could be used to debug bootloaders. Previous versions of CCS (v3.3 and older) did not contain Linux awareness but it is currently being added to CCSv4 which is in the beta phase. It should be possible to debug the kernel and user space once CCSv4 is released. See Linux_Aware_Debug for more information.
[edit] Oprofile
OProfile is a system-wide profiler for Linux systems, capable of profiling all running code at low overhead. It consists of a kernel driver and a daemon for collecting sample data, and several post-profiling tools for turning data into information
OProfile is optional component during KERNEL build. It may have been enabled by default. You can confirm that the kernel has OProfile support, by looking for following lines in the <mydroid_folder>/kernel/.config file
CONFIG_OPROFILE_OMAP_GPTIMER=y CONFIG_OPROFILE=y CONFIG_HAVE_OPROFILE=y
Hardware Configuration
The Hardware Configuration required to execute the test cases includes:
Linux machine (can be with your favorite distro) TCP/IP configuration on Zoom2 board Zoom2 Board
Software Configuration
The Software Configuration required to execute the test cases includes:
Tera Term (or any terminal program) Graphviz on Linux machine (Use this command on Host terminal $ sudo apt-get install graphviz GPROF2DOT python script (Copy the script to any location in your path (e.g. in ~/bin of your Linux machine); Ensure that ~/bin is exported in the PATH Run the following command - $ cd ~/bin && chmod 777 gprof2dot.py
Installation
This step should be done after the android file system has been built.
$MYDROID is the location where the android SDK is installed. eg: export MYDROID=/home/$user/Lxx.x/mydroid
Edit the $MYDROID/external/oprofile/opimport_pull script as follows:
Remove the python version number from the first line eg. change #!/usr/bin/python2.4 -E to #!/usr/bin/python -E Append the following lines at the end of the file to generate cpuloads.txt and callgraph.png for further analysis os.system(oprofile_event_dir + "/bin/opreport --session-dir=. >> cpuloads.txt") os.system(oprofile_event_dir + "/bin/opreport --session-dir=. -p $OUT/symbols -l -t 0.1 >> cpuloads.txt") os.system(oprofile_event_dir + "/bin/opreport -cg --session-dir=. -p $OUT/symbols > callgraph.txt") os.system("cat callgraph.txt | gprof2dot.py -s -w -f oprofile -n 1 -e 1 | dot -Tpng -o callgraph.png") Since we perform the post-processing on host, we don't need the actual vmlinux file (~40 MB) on target. Make sure that you create a dummy file named "vmlinux" in the root directory to satisfy opcontrol arguments. #echo 0 > /vmlinux
Execution
Set-up OProfile directories
Make sure that you have created an empty file and named it vmlinux as described in above section. Run the following command on the target # opcontrol --setup By default there should be no output. In case you see, "Cannot create directory /dev/oprofile: File exists do_setup failed#", it means that, OProfile is not built in the Kernel. Verify that you have selected OProfile in make menuconfig step of Kernel build (Refer Configuration Section)
Initialize the OProfile daemon
The kernel range start and end addresses need to be verified on the setup for each release using: # grep " _text" /proc/kallsyms c0030000 T _text # grep " _etext" /proc/kallsyms c03e1000 A _etext Note: You need busybox installed for this command to work. Refer here if you havent set-up busybox Using the above addresses, run the following command # opcontrol --vmlinux=/vmlinux --kernel-range=0xC0030000,0xC03e1000 --event=CPU_CYCLES:64 You should see the following output on your terminal Cannot open /dev/oprofile/1/enabled: No such file or directory Cannot open /dev/oprofile/2/enabled: No such file or directory Using 2.6+ OProfile kernel interface. Reading module info. Using log file /data/oprofile/samples/oprofiled.log # init: untracked pid 914 exited Increase the Back trace depth, so that more details can be captured in the log # echo 16 > /dev/oprofile/backtrace_depth To ensure that everything is ready, you can run the following command # opcontrol --status The following output should be seen. Note that the PID will change depending on your system. Driver directory: /dev/oprofile Session directory: /data/oprofile Counter 0: name: CPU_CYCLES count: 64 Counter 1 disabled Counter 2 disabled oprofiled pid: 915 profiler is not running 0 samples received 0 samples lost overflow
Starting and Stopping the profiler
Run the following command to start the profiler # opcontrol --start and use the command below to stop the profiler # opcontrol --stop
Generating the Results
We need to run the following steps on the Host machine (that has android SDK/build) to generate the results.
On command prompt of Host machine (that has android SDK/build), do the following $ cd $MYDROID $ source build/envsetup.sh $ setpaths $ export ADBHOST=<ip address of ZOOM2 board> The IP address of the ZOOM2 board can be found during boot-up phase e.g. : IP-Config: Got DHCP answer from 0.0.0.0, my address is 128.247.79.152
Post-process OProfile results
This needs to be done from the PC where Android SDK is installed. Go to the terminal on host PC and do the following: $ cd $MYDROID/external/oprofile/ $ ln -s $MYDROID/kernel/android-2.6.27/vmlinux $OUT/symbols/vmlinux $ opimport_pull <new_dir_to_store_dump_and_results_on_Linux_machine> The following files and the Callgraph image can be referred for OProfile results. They will be generated in the <new_dir_to_store_dump_and_results_on_Linux_machine> in step above cpuloads.txt callgraph.txt