android native crash

###1. deadbaad android中有时候遇到native crash, 在log中显示“fault addr deadbaad”, 例如 19:15:37.209 565 0 I Kernel : <6>[ 1389.481323] system_server[920]: unhandled level 1 translation fault (11) at 0xdeadbaad, esr 0x92000045 19:15:37.214 565 0 I Kernel : <1>[ 1389.481335] pgd = ffffffc06462a000 19:15:37.214 565...

linux进程的内存布局

###1. 32位linux下进程内存空间的经典布局 动态链接库也被映射到mmap区域 这种布局 mmap 区域与栈区域相对增长,这意味着堆只有 1GB 的虚拟地址空间可以使用,继续增长就会进入 mmap 映射区域,这显然不是我们想要的。这是由于 32 模式地址空间限制造成的,所以 内核引入了前一种虚拟地址空间的布局形式。但是对 64 位模式,提供了巨大的虚拟地址空间,这个布局就相当好。如果要在 2.6.7 以后的内核上使用 32 位模式内存经典布局,可以使用如下任意命令来设置: $ sudo sysctl -w vm.legacy_va_layout=1 $ ulimit -s unlimited ###2. 32位linux下进程内存空间的默认布局 动态链接库也被映射到mmap区域 从上图可以看到,栈至顶向下扩展,并且栈是有界的。堆至底向上扩展, mmap 映射区域至顶向下扩展, mmap 映射区域和堆相对扩展,直至耗尽虚拟地址空间中的剩余区域,这种结构便于 C 运行时库使用 mmap 映射区域和堆进行内存分配。上图的布局形式是在内核...

VDSO和系统调用

###1. VDSO VDSO就是Virtual Dynamic Shared Object,就是内核提供的虚拟的.so,这类.so文件不在磁盘上,而是包含在内核里面。内核把包含某一.so的物理页在程序启动的时候映射入其进程的内存空间,对应的程序就可以当普通的.so来使用里头的函数 linux上目前使用的vdso是“linux-vdso.so.1”(旧版的名称可能是“linux-gate.so.1”), 通过ldd命令可以发现,基本所有的应用都会依赖这一so $ ldd cat linux-vdso.so.1 => (0x00007fff47ffe000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f45f6af2000) /lib64/ld-linux-x86-64.so.2 (0x00007f45f6ecc000) VDSO在进程中映射的地址可通过如下方式来查看: $ cat /proc/xxx/maps | grep vdso 需要注意的是, 新的内核中提供了的进程地址随机化功能, 因此,linux-vdso.so.1每一次的映射地址都不相同(即使是对于同一个可执行程序), linux中的”/proc/sys/kernel/randomize_va_space”用于控制linux的进程地址随机化, 取值如下: 0 : 表示关闭内存地址随机化 1 : 表示将mmap的基址,stack和vdso地址随机化 2 :...

ELF 文件结构

###1. elf ELF(Executable and Linking Format)是一种对象文件的格式,用于定义不同类型的对象文件(Object files)中都放了什么东西、以及都以什么样的格式去放这些东西。它自最早在 System V 系统上出现后,被 NIX 世界所广泛接受,作为缺省的二进制文件格式来使用。可以说,ELF是构成众多NIX系统的基础之一 TISC(Tool Interface Standard Committee)委员会定义了一套ELF标准, 前后共有两个标准:v1.1和v1.2, 两个版本的内容差别不大 ELF定义的是对象文件的格式, 所谓对象文件(Object files)有三个种类: 1. 可重定位的对象文件(Relocatable file) : 这是由汇编器汇编生成的 .o 文件,链接器会使用一个或一些 Relocatable object files 作为输入,经链接处理后,生成一个可执行的对象文件 (Executable file) 或者一个可被共享的对象文件(Shared object file)。我们可以使用 ar 工具将众多的 Relocatable...

gdb 远程调试在android上的应用

###1. gdb 远程调试 如果要调试运行于一个不能运行GDB的机器上的程序时,使用远程调试就很有帮助了。例如,可以用远程调试操作系统内核,或者在小型的,没有足够的操作系统能力来支持运行完全功能的调试器的系统里调试, gdbd的远程调试采用gdb+gdbserver的远程调试方法:gdbserver在目标板中运行,而gdb则在主机上运行(主机上的gdb是特殊版本, 可在主机上运行, 但是针对目标平台编译, ) GDB可以配置特殊串口和TCP/IP接口来支持远程调试特殊的调试目标。另外,GDB还有通用串口协议(特指GDB,不是指任何特殊目标系统),如果你可以用它实现远程代理–远程代理的代码运行于远程系统,用来和GDB通讯 Android 上通常都自带了gdbserver的源码并且编译出可执行文件,需要注意的是, 64位系统上一般带有2个版本: gdbserver, gdbserver64, 需要跟据要调试的程式选用正确的版本 而gdb则可以使用编译android的源码所使用的交叉编译器中自带的gdb, 其路径可使用如下的方式 $ source build/envsetup.sh $ lunch $ env | grep ANDROID_TOOLCHAIN 使用获取的路径中的 *gdb 即可 宿主机上的gdb使用“target remote”命令来连接gdbserver, 对于串行线和tcp/udp方式的usage 分别如下 target remote serial-device target remote host:port...