android coredump

我们开发Android本地可执行程序时,常常遇见segment fault错误,若程序比较复杂,使用打日志的方式很难查到出错的根本原因,若能让程序出core,然后用gdb 调试该core文件将能很快定位出错的代码位置,并能看到运行时出错代码的运行栈,这样能迅速定位。

1. core dump

那什么是core dump呢,core dump是指当程序运行崩溃的瞬间,内核会抛出当时该程序进程的内存详细情况,存储在一个core.xxx的文件中,Android默认设置情况下,程序运行出错后是不会出core的,需要进行以下设置:

  • 1) 设置core文件的存储位置

    echo “/data/coredump/core.%e.%p” > /proc/sys/kernel/core_pattern

    表示存储在 /data/coredump 下,%e表示程序的名字,%p是指进程号, 示例:core.adbd.235

    若不设置core文件的存储位置,core文件将保存在程序运行时的工作目录下,文件名是core

    若想系统启动时自动设置core文件的存储位置(这样不用每次开机都需要重新设置),可以在根文件系统的init.rc里添加命令:

    on init
      ...
      write  /proc/sys/kernel/core_pattern /data/coredump/core.%e.%p
      ...
  • 2) 设置core文件大小限制

    默认情况下系统限制core文件大小为0,此时程序运行出错无法出core,若使用ulimit -c命令查看,可以看到结果是0,这时候可用ulimit -c unlimited 设置core文件大小无限制,此时运行程序出错后,便可以出Core了。但是请注意使用ulimit命令修改core限制,只针对此次会话有效,也就是说你使用adb shell 设置好后,在另外一个终端里运行adb shell后,再运行程序出错,还是不会出Core。

    若想对所有会话都有效,需要在系统启动时,就进行这样的设置。但是ulimit是一个shell内置命令,故此不能在init.rc里添加调用ulimit命令的服务来解决该问题,此时有三种解决方法,修改现有init.rc里的服务对应程序的源代码,或者修改init的源代码,或者编写一个本地程序,并在init.rc添加一个服务调用该程序,取消core文件大小限制的关键代码如下:

    1
    2
    3
    4
    
    struct rlimit lim;
    lim.rlim_cur=RLIM_INFINITY;
    lim.rlim_max=RLIM_INFINITY;	 
    setrlimit(RLIMIT_CORE,&lim); //出core

    你可以将该段代码添加到你的本地程序里或者init源代码,或者服务程序源代码里。这样系统启动后,程序异常退出时,便会出core。此种方式对调试adbd程序非常有帮助。

2. 使用gdb调试出Core的程序

调试出现segment fault的本地程序时,别使用优化后的程序,这样使用gdb调试时不能看到源代码,都是一堆的二进制代码。Android源代码开发时,优化前的程序位于目录out/target/product/m7cdug/symbols下(m7cdwg是某个产品),你可以在该目录下使用find 命令查找你要调试的程序: find -name “progname”。

程序出core后,使用adb pull将core文件从手机上拉下来,再将该文件放置到源代码开发主机的优化前程序所处目录下。如果你在编译Android源代码,并使用了source build/envsetup.sh,此时在编译源代码的终端可以运行arm-eabi-gdb命令来调试core文件,若找不到该命令,先将该命令所在目录添加到PATH目录。调试core文件的命令:arm-eabi-gdb 被调试程序 core,示例:

1
arm-eabi-gdb adbd core.adbd.235

注意:

使用该命令时,可能会出现问题:libpython2.6.so.1.0: cannot open shared object file,此时需要安装 python 2.6

先下载python 2.6并解压,http://www.python.org/ftp/python/2.6/Python-2.6.tar.bz2

编译并安装

./configure --prefix=/opt/python26 --enable-shared --enable-unicode=ucs4 #安装至/opt/python26
make && sudo make install 
sudo ln -s  /opt/python26/lib/libpython2.6.so.1.0   /usr/lib/libpython2.6.so.1.0 #软链接

调试时比较常用的命令:

bt:查看异常时的堆栈,使用gdb调试Core文件时,一般用该命令先查看出错的源代码位置

list: 查看当前堆栈指针指向的源代码的前后共10行代码

up n: 堆栈指针往上移动n层

down n:堆栈指针往下移动n层

frame: 查看堆栈指针指向当前堆栈的位置

print: 查看某个变量 示例:print a


from:  http://www.cloudchou.com/android/post-307.html

http://m.blog.csdn.net/blog/handyhuang/17010489#

#000

   保证开发板,windows主机,linux虚拟机 3者互联互通

   linux虚拟机 ip 192.168.1.100

   windows主机ip 192.168.1.102

   linux开发板 ip 192.168.1.103(eth0) 

#001 NFS调试

   linux虚拟机
   
/etc/exports 文件增加一行 /your/board_rootfs/path/ROOTFS*(rw,sync,no_root_squash)
   
/etc/init.d/nfs restart 重启nfs
服务
   
将编译好的板子程序 app_test,拷贝到/your/board_rootfs/path/ROOTFS/root/

   linux开发板
 
   设置启动参数,不同开发版有差异,重点在紫色和蓝色部分
     
setenv bootargs 'console=ttyS0,115200 root=/dev/nfs rwnfsroot=192.168.1.100:/your/board_rootfs/path/ROOTFSip=192.168.1.103::192.168.1.1:255.255.255.0::eth0:LX_MEM=0x2300000EMAC_MEM=0x100000 DRAM_LEN=0x10000000 LX_MEM2=0BB_ADDR=0xFFFFF00,0MS_GOP0_MIU=0 mtdparts=edb64M-nand:120m(UBI),-(NA)'

   saveenv 

    重启开发板,等待开发板挂载linux虚拟机里的根文件系统,成功后,可以通过SecureCRT等软件登录到开发板
 
    cd /root/
     ./app_test
  
    就可以运行app_test程序,另外可以按需修改开发板的/etc/init.d/rcS文件

#002 程序崩溃产生core文件

   linux开发板
 
   运行app_test前,执行如下指令
     ulimit -c unlimited
     如果程序崩溃没有core文件,可以确认是内核问题。例如mstar的开发板,必须在/application下面执行才生成core文件。程序崩溃后,在app_test同级目录产生Coredump.gz 文件 

   linux虚拟机
 
   gzip -d Coredump.gz (此命令解压Coredump.gz后产生Coredump文件,自动删除掉Coredump.gz)
     /opt/mstar/mips-4.3/bin/mips-linux-gnu-gdb -c Coredump  app_test
     setsolib-search-path/your/board_rootfs/path/ROOTFS/lib
     core-file
     core-fileCoredump
     bt

    就会看到崩溃的堆栈信息


你可能感兴趣的:(android)