Chinaunix首页 | 论坛 | 博客
  • 博客访问: 282783
  • 博文数量: 17
  • 博客积分: 2096
  • 博客等级: 大尉
  • 技术积分: 535
  • 用 户 组: 普通用户
  • 注册时间: 2006-11-28 18:55
文章分类

全部博文(17)

文章存档

2010年(16)

2008年(5)

分类: 嵌入式

2010-05-06 14:20:43

Android Debugging

From OMAPpedia

Jump to: ,

Contents

[]

[] Eclipse ADT

[] Note on Installing Eclipse Plugins

Before installing the Android Development Tools, be sure to put your proxy server (if applicable) into the General preferences under Network Connections and to "install" the software update link to the version of Eclipse you have (3.5 is ").

You will likely have to install several required plugins from Eclipse before ADT will install (possibly GEF and WST plugins).

[] 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: Upon 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. If you havent added ip=dhcp in the bootargs, you can start the ethernet and obtain an IP address using dhcp using following commands

   # netcfg eth0 up
   # netcfg eth0 dhcp

Using the command below you can verify that the board did obtain an IP address

  # netcfg

NOTE: If you boot via NFS, then uboot will typically print out the board's IP address to console.


On the host machine run the following commands from terminal shell:

  $ export ADBHOST=
  $ 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.

[] Troubleshooting

Issue: ADB is not in the path, where should I find it?

Resolution: ADB command line tool is found at: /out/host/linux-x86/bin/

Issue: ADB is having a problem connecting over Ethernet.

Resolution: This is because the ADB stub on target defaults to USB. To fix this, in the Zoom console:

      # setprop service.adb.tcp.port 5555


This will avoid ADBD defaulting to USB transport. Restart ADBD on Zoom to take the changed settings.


      # stop adbd
      # start adbd

Alternatively, the setprop command can be included in init.rc so that system property is set at start up, before starting ADB stub.

[] 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.


[] 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=

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: 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:


You may have to run the following after each target reboot:

       adb kill-server


[] 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:

Image:DDD.jpg

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 ddd

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=

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: 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:

You may have to run the following after each target reboot:

       adb kill-server

[] 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.






[] 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. It should be possible to debug the kernel and user space once CCSv4 is released. See for more information.

[] Selectively Enable Opencore Debug Print

To utilize the existing log statements without rebuilding the whole PV library, you can do this:
1. In the beginning of the file, after the last "#include" line, add following:

  1. include
  2. undef LOG_TAG
  3. define LOG_TAG "YOUR_MODULE_NAME"
  4. undef PVLOGGER_LOGMSG
  5. define PVLOGGER_LOGMSG(IL, LOGGER, LEVEL, MESSAGE) JJLOGE MESSAGE
  6. define JJLOGE(id, ...) LOGE(__VA_ARGS__)


2. In the end of the file, add these:

  1. undef PVLOGGER_LOGMSG
  2. define PVLOGGER_LOGMSG(IL, LOGGER, LEVEL, MESSAGE) OSCL_UNUSED_ARG(LOGGER);


You can play with the macro to filter based on level too.

[] Profiling

There is a simple profiling mechanism implemented in the kernel, implemented by storing the current instruction pointer at each clock tick.

To enable profiling, pass the boot argument

           profile=N 

where N is a number which determines the granularity of profiling. The lesser the number, the more the granularity of profiling.

A busybox utility named 'readprofile' is available to process the profiled data. 'readprofile' requires the kernel symbol table file 'System.map' to resolve the symbols.

To clear the profiled data:

    $readprofile -r

To display the profiled data:

    $readprofile -m /System.map|sort -nr
    You should see an output similar to the following:
    1415 total                                      0.0003
     1153 omap3_enter_idle                           3.3132
       28 schedule                                   0.0304
       15 omap_i2c_isr                               0.0179
       12 v7wbi_flush_user_tlb_range                 0.1579
       11 copy_page                                  0.1146
       10 __memzero                                  0.0781
        8 __copy_to_user                             0.0085
        6 update_mmu_cache                           0.0341
        5 sub_preempt_count                          0.0260
        5 mmc_queue_map_sg                           0.0305
        5 handle_IRQ_event                           0.0431
        4 unmap_vmas                                 0.0027
        4 filemap_fault                              0.0038
        4 __do_fault                                 0.0042
        3 vsnprintf                                  0.0013
        3 up_read                                    0.1500
        3 omap_hsmmc_enable_clks                     0.0069
        3 kmem_cache_alloc                           0.0208
        3 get_page_from_freelist                     0.0025
      ....

The first column gives the number of ticks and the last column gives the number of ticks divided by function size.


This profiler covers only the kernel. For system wide profiling and advanced options, OProfile can be used.


[] 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 /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  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 0.1 -e 0.1 | dot -Tpng -o callgraph.png") 
  

On Eclair we have seen the Android tools opannotate, oparchive, opimport and opreport tools in prebuilt/linux-x86/oprofile/bin/ folder are not working properly.

These binaries (tar balled) from donut are available @ Oprofile.tar.gz. Download this .gz file to $MYDROID folder

     cd $MYDROID
     tar xvf Oprofile.tar.gz

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 if you haven't 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=

Note: This should be done @ $MYDROID level (where the build was set-up otherwise, it wouldn't work)

If ADB over Ethernet is not working refer to here

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.29/vmlinux $OUT/symbols/vmlinux 

On eclair, creating symbolic link doesnt work properly. Instead just create a copy of vmlinux (and dont forget to update this copy of vmlinux if you rebuild the kernel)

          $ rm $OUT/symbols/vmlinux
          $ cp $MYDROID/kernel/android-2.6.29/vmlinux $OUT/symbols/vmlinux 

In case, you are using OPROFILE binaries that were not build on your machine, you might have to create a symbolic link to zoom2 folder, since OProfile looks there

          $ ln -s $MYDROID/out/target/product/zoom2 $MYDROID/out/target/product/generic

Generate the OPROFILE results using the command below

          $ opimport_pull  


The following files and the Callgraph image can be referred for OProfile results. They will be generated in the in step above

Note: If there are some binaries that are compiled on WINDOWS and linked in to your build :( - you will see the message below

          Traceback (most recent call last):
            File "/home/user/bin/gprof2dot.py", line 1965, in 
              Main().main()
            File "/home/user/bin/gprof2dot.py", line 1890, in main
              self.profile = parser.parse()
            File "/home/user/bin/gprof2dot.py", line 1062, in parse
              self.parse_entry()
            File "/home/user/bin/gprof2dot.py", line 1112, in parse_entry
              function = self.parse_subentry()
            File "/home/user/bin/gprof2dot.py", line 1136, in parse_subentry
              filename, lineno = source.split(':')
          ValueError: too many values to unpack
          cat: write error: Broken pipe

In this case, you can open callgraph.txt in in your favourite editor. Search for ":\" and delete the "" in front of that line.

For eg. if you have E:\workspaces\ make it \workspaces\

Now, cd to and run the following command to generate callgraph.png manually

         # cd 
         # cat callgraph.txt | gprof2dot.py -s -w -f oprofile -n 0.1 -e 0.1 | dot -Tpng -o callgraph.png

The guidelines and caveats while interpreting Oprofile results are available at




[] Strace

Recommended Usage on target

       # strace -ff -F -tt -s 200 -o /sqlite_stmt_journals/strace -p 


Note

-ff makes strace follow fork() and output each forked files trace to a different file

-F means we try and follow any vfork()s.

-tt prints out the time of system calls in microseconds

-s 200 so that we can see a bit more detail in any strings that are used.

[] Using INST2 for Performance Measurement on DSP

INST2 is a tool that helps us measure DSP MHz used for a particular use case e.g. Video playback or record.

It is recommended that the OPP is locked before starting this tool for obtaining accurate result.

To lock the OPP use the following commands:

    # echo n > /sys/power/vdd1_lock
    # echo n > /sys/power/vdd2_lock

(where n stands for the OPTIMAL OPP the use case should run at)

Refer to this file for the OPP table corresponding to your chip

After executing your usecase, make sure that OPP locks are removed using the command below

    # echo 0 > /sys/power/vdd1_lock
    # echo 0 > /sys/power/vdd2_lock

Step 1: Install busybox on the target filesystem.

Copy the pre-built at /data/busybox/

On target do the following

 # cd /data/busybox/
 # chmod 777 busybox
 # busybox  --install
 # export PATH=/data/busybox/:$PATH

Incase the "busybox --install" fails with message "Busybox not found" error, check with ls command to confirm if busybox is actually present and then try "./busybox --install"

Step 2: Download the Dsp_load_measurement_tool.tar.gz file to your host machine

Untar this file using the command below

   $ tar xvf Dsp_load_measurement_tool.tar.gz
   $ cd dsp_load_measurement_tool 
   $ tar xvf inst2.tar

Copy /dsp_load_measurement_tool/inst_log file to the root directory in your file system; using SD card or adb push

   # cp inst_log .
        OR  
   $ adb push inst_log .

Step 3: Give permissions to the files copied

    # cd /
    # chmod 777 inst_log

Step 4: Now run the use case i.e. start playback or record

Step 5: Run the instrumentation

    # ./inst_log

Following messages should appear

       DSP device detected !!
       DSPProcessor_Attach succeeded.
  

Step 6: Once the use case is complete (i.e. playback or record is done), wait for "INST: Log file written. Waiting for INST DSP side cleanup" message

Step 7: Now wait for "INST: DSP Cleanup done. Exiting" message. If this msg does not appear, run the use case once more and wait again for a "INST: DSP Cleanup done. Exiting" message. Basically this will flush previous results and you do not need to run the full use case again.

This is to make sure previous result is flushed out.

Step 8: Bring the "log.bin" on HOST PC. This gets generated in /sqlite* folder of target FS.

     # cp /sqlite*/*.bin /
     # cp log.bin /sdcard OR 
     # sync

Step 9: On the HOST PC use the following command line to generate the results.

Go to following folder:

     $ cd dsp_load_measurement_tool\inst2\tools
     $ perl inst_load.pl -c log.bin
     for example      
     $ perl inst2/tools/inst_load.pl -c660 log.bin

On the screen you will see information about the file for example:

   Number of records: 40731
   splice() offset past end of array at inst2/tools/inst_load.pl line 123.
   Range #0 - beg: 0, end: 40731, length: 40731
   Range #1 - beg: 0, end: 40731, length: 40731
   Ignoring IDLE traces 0-22 and 40714-40730
   Clock Freq:   660 MHz
   Total Cycles: 25383675998
   Event |  Handle_Event |    Cycles |  Evts/s | ms/Evt |   MHz |30 Evt/s MHz
   ------+---------------+-----------+---------+--------+-------+------------
   unkwn | 00000000_0000 |     11568 |       0 |      0 |     0 |
   IDLE  | 00000000_2001 | 1.396e+10 |   48.99 |  11.23 |   220 |
   UALG  | 2025fad4_2009 |  70257552 |      39 |   0.07 |   1.1 |   0.85
   CTRL  | 2025fad4_2011 |     40768 |    0.19 |   0.01 |     0 |
   RESET | 2025fad4_2021 |    762453 |     0.3 |    0.1 |     0 |
   USN   | 2025fad4_2041 |  47083524 |   50.17 |   0.04 |   0.7 |
   ALGO  | 2025fad4_2101 | 560448611 |   19.68 |   1.12 |   8.8 |  13.46
   UALG  | 20260ee4_2009 | 2.320e+09 |   25.56 |   3.58 |  36.6 |  42.91
   CTRL  | 20260ee4_2011 |     21475 |    0.13 |   0.01 |     0 |
   RESET | 20260ee4_2021 |    286269 |    0.05 |   0.24 |     0 |
   USN   | 20260ee4_2041 | 116914279 |   76.21 |   0.06 |   1.8 |
   ALGO  | 20260ee4_2101 | 8.305e+09 |   25.54 |  12.81 | 130.9 |  153.7


Look at the last row, in above results. In this case the algo. consumed 130 Mhz. and it was running @ 25.54 fps. If we interpolate that to 30 fps, the effective Mhz would be 153.7

Step 10: The final step is to apply the next formula:

       DSP Mhz consumption = (Clock Freq - IDLE MHz). 

For example in this case above the DSP CPU Load is 400-220 = 180 MHz

Retrieved from ""
 
 
阅读(3268) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~