作者robinliao (qqq)
看板LinuxDev
标题[心得]2011/12 SA@Tainan 用Android学习系统程式
时间Sun Jan 29 14:10:38 2012
[补充jserv大大的feedback]
各位大大好:
这份是 【2011 十二月份 SA@Tainan 用 Android 学习系统程式 12/24 (六) 】
课程的心得。
感谢工作人员和讲师的付出,整理一份当时抄的笔记,由於年代已久不可考,有些
其实已经忘记当初要记的重点。
这份笔记主要是补充投影片中的东西和自己有兴趣的内容,建议搭配投影片和紫皮
书【程式设计师的自我修养:连结、载入、程式库】。投影片可以到jserv 大大的
网站或是【酷!学园】讨论区上面都有。
另外我想应该很多错误也请指正,谢谢!
* Android IPC
- Intent -> AIDL -> Binder
- cat /sys/kernel/debug/binder 可以观察相关资讯
- Parcel打包概念
- binder 是去shared memory 捞service
- 所有service透过binder 相互联系
* Android debuggerd
- Android 拦胡process segmentation fault signal,发生不正常错误时透过
socket 通知debuggerd
- debuggerd在logcat中显示的address是上次跑完的address
- lr -> register for storing return address in ARM
- 可以比照crash log和/proc/pid/maps
- 参考:
https://wiki.linaro.org/WorkingGroups/ToolChain/Outputs/LibunwindDebuggerd
* Dynamic linker/program interpreter
- 同一个 root file system 底下可有两个以上的 ELF interpreter
- Android下面不同的版本/system/bin/linker的address可能不同
+ 安全性考量以及performance因素
- X86
+ Entry: libc_start_main
+ library: libc
+ linker: ls-linux.so.2 (可以执行)
- Android
+ Entry: __libc_init
+ library: bionic
+ linker: /system/bin/linker
- 没有正确处理 stack & calling convention,会发生 SegFault
* bionic (Android的libc)
- __init_libc有static和dynamic 两种方式
- init process (pid 1 那个)用static,不可用malloc
- 相关说明可以参考AOSP下面的文件(有点过期)
- adbd 是static (?)
- 看interpreter资讯
- objdump -s -j .interp filename
* memory map of a process
- cat /proc/pid/maps
+ 栏位说明:
- address
- perms
+ r = read
+ w = write
+ x = execute
+ s = shared
+ p = private (copy on write)
- offset
- dev
- inode
- pathname
- 相同的path有两个以上可能是text/data的差别
adb shell cat /proc/18696/maps (投影片剪贴)
00008000-00009000 r-xp 00000000 b3:02 8959 /data/local/hello
00009000-0000a000 rwxp 00001000 b3:02 8959 /data/local/hello
b0001000-b0009000 r-xp 00001000 b3:01 128 /system/bin/linker
b0009000-b000a000 rwxp 00009000 b3:01 128 /system/bin/linker
b000a000-b0015000 rwxp 00000000 00:00 0
beb07000-beb28000 rw-p 00000000 00:00 0 [stack]
ffff0000-ffff1000 r-xp 00000000 00:00 0 [vectors
- heap是由address往後面增加
- stack是由address往前面增加
- 可以用来逆向以及trace程式
* ABI
- readelf可以读出来
$ readelf -h ../libs/armeabi/a
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: ARM
Version: 0x1
Entry point address: 0x8540
Start of program headers: 52 (bytes into file)
Start of section headers: 7592 (bytes into file)
Flags: 0x5000002, has entry point, Version5
EABI
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 7
Size of section headers: 40 (bytes)
Number of section headers: 22
Section header string table index: 21
- eabi/oabi: e for embedded, o for old
- 不同的ABI (包含ABI版本)对於data type的size定义有可能不同
+ sizeof (char)
- EABI: 1
- OABI: 4
+ sizeof (struct empty_struct{};)
- EABI: 1
- x86没有ABI版本的问题
- Embedded的ABI不同的原因可能是
+ 改板
+ 商业考量,故意让其他产品不能相容
+ 效率
+ ref:
http://wiki.debian.org/ArmEabiPort
- ARM EABI 基本上已大一统了
* Start a process
- create a process
- load executable file
- setup runtime
- page valid (?)
* Before Hello World..
- UID/GID
- Signal
- load ld.so
- mmap
- random
- load libstdc++.so
- ...
* Android GDB
- adb forward tcp:port tcp:port
- symbol 可能在
- ${PWD}/out/target/product/product_name/symbols/system/bin
* LD debug
- export LD_DEBUG=files
- LD_DEBUG=help /lib/ld-2.13.so
* Hear Say/忘记是记啥的
- BUILD_ID
+ Issue tracking
- 忘记讲的是ELF还是AOSP/Cyanogenmod
- NDK的进版本和Android SDK进板有关联
- mm -b => make clean; make
- 有些elf执行档没有main的进入点
+ pypy
- 2010年开始ELF加入build ID
- abort()
- ptrace
- addr2line -e [file]
- Android重写了libc/linker,size减少,代价就是功能也减少
- libunwind
- ELF section的offset一般来说会和/proc/pid/maps会有点差别,主要是安全考量
- ANR
+ Android Not Responding
+ 执行很久的程式码,建议放在 Service 中
- Android中把东西mix起来就叫flinger
+ Surface flinger
+ service flinger
+ ...
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 111.250.98.253
1F:推 alongalone:推.... 虽然我跟android很不熟..Orz 01/29 15:58
※ 编辑: robinliao 来自: 111.250.98.253 (01/29 18:14)