Updated gas-preprocessor to handle clang’s issue related to -g option

clang included in Xcode 4.3.x (LLVM 3.1) has an odd issue when it is used with gas-preprocessor.

As you may know, gas-preprocessor adds “-S” to compiler’s command line to generate assembler source, does some preprocessing on it, then invokes compiler again. The compiler then invokes assembler to create final objective code. Here, compiler is clang and assembler is apple as.

If  a “-g” is specified in clang’s command line, clang will generate dwarf-2 debug information directives into assembler source. When clang gets invoked again, it will also take “-g” into apple as’s command line options. Unfortunately, as declines those debug information directives, including .file and .loc, if it is iovoked with “-g”.

So, I have to add a hack into gas-preprocessor. If -g is in command line, eliminate it in 2nd compiler invocation.

See latest commit in https://github.com/hollylee/gas-preprocessor

 

用 Instruments 来分析 iPhone 应用程序

注意哦, 这里说的不是你自己的应用, 那个太简单容易了, 没什么挑战, 不值得在这里写一篇 blog.

目标: 用 Instruments 来 profiling 第三方的应用, 没有源码的, 只有 binary 的.

Apple 在系统中对 Instruments 运行有一个限制: 在碰到使用 distributed certificate 做 codesign 的 app, 不予运行, 直接 kill 9.

所以, 我们需要有一个可用的 developer certificate. 然后就很简单了.

codesign -fs "iPhone Developer: Holly Lee" --resource-ruls ResourceRules.plist --entitlements Entitlements.xml AppBinary

好了之后放入 iPhone 里覆盖原来的 binary, 然后运行 Instruments 选择该 app 就行了.

当然, 默认的前提是: iPhone 需要 jailbroken 先.

Objective-C(++) 的一些细节注意点

  • 如果把 objc 类放到一个库中, 然后在主程序里并不直接引用到类本身的构造, 而是通过诸如 .xib 中命名或者类似的  serialization 方式使用这个类的话, 需要在 Linker flags 中加入 -ObjC, 否则该类不会被正确构造. 一个例子是将一个 customized view 放到 .a 中, 然后在 xib 中将一个 view 的 class 设为此 custom view, 在主程序中 load 之后, 会发现其实只产生了一个 UIView 而未产生正确的 CustomView. 解决方法就是将 -ObjC 加入到 linker flag. 如果还不行的话, 还有最后一招 -all_load. 这个 linker flag 的意思是不管三七二十一, 把所有东西都连到最后的 binary 里.
  • 作为 Objc 类的成员定义的 C++ 类, 在默认情况下, 其非默认形式的构造函数和析构函数是不会在 objc 类 init 和 dealloc 时被调用的. 要让 objc 在 init 和 dealloc 时调用作为其成员的 C++ 类的非默认构造函数以及析构函数, 必须加上这个编译器参数:  -fobjc-call-cxx-cdtors. 另外, 如果使用了 NSZombieEnabled, 无论是否有上述编译器参数, 构造和析构函数都不会被调用到.

Build android source on SnowLeopard with xcode4

1) Install 10.5 SDK from xcode 3’s dmg

2) Specify “CC=gcc-4.2 CXX=g++-4.2 CPP=cpp-4.2” before make command line to avoid an issue in default llvmgcc-4.2. Of course you can change the gcc symbolic link to what you want but I think it doesn’t make sense for this exception. llvmgcc works on most cases. I just found two exceptions till now – one is Android source, the other is ffmpeg.

 

FaceTime会话建立过程的技术猜测

Jobs在WWDC10上提到,FaceTime将会是一个开放标准,也就是说,不仅iPhone4-iPhone4可以通话,任何支持这一标准的应用都加与之通话。因此,值得我们观注一下。

FaceTime最吸引人的地方在于,居然不用预先维护联系人,而各种即时通信工具都需要你这样做,也不需要你登录某个服务器,直接拨电话号码就可以,真正是零配置,这对于普通用户来说,体验真是好极了。

那么FaceTime是怎么做到这一点的呢?由于手头并没有iPhone4,连能跑iOS4的机器都没有,只能根据Jobs在发布会上提到一堆术语来猜测了,有条件的朋友不妨抓个包,看看是不是这么回事。

已知会话使用SIP协议完成,这就好办了。想来应该是这样一个过程:

  1. app启动或检测到wifi网络连接变化
  2. app从SIM卡里取得必要信息,用本机手机号@facetime.apple.com之类的URI注册到Apple家的SIP服务器上。
  3. 用户拨一个电话号码
  4. app按照SIP规范拼装100 invite包,发给apple的服务器,from为本机手机号,to为被叫手机号
  5. SIP服务器响应trying,并在内部查找
  6. SIP服务器根据URI找到对应用户的当前记录
  7. SIP服务器根据被叫方登记的地址和端口,将invite转给被叫手机
  8. 被叫手机上的app收到invite,开始振铃,并发180 ringing包给SIP服务器
  9. SIP服务器将ringing包转给主叫方
  10. 主叫方手机开始显示对方正在振铃
  11. 被叫用户接受通话
  12. 被叫方app发200 OK包
  13. SIP服务器将200 OK包转给主叫手机
  14. 现在双方都知道对方的地址和端口了,200 OK包的内容是一个SDP描述,用于协商如何建立数据流
  15. 主叫方发ACK包给被叫方,这个包就不再需要服务器中转了
  16. 双方app开始用RTP建立视音频流
  17. 双方app通过RTP接叫对方的h.264视频流,同时将本机摄像头的h.264码流封装成RTP包发出

如果成为开放标准,参与这会话过程的SIP服务器可以有多个,它们会接力转发invite/ringing/ok包,除了SIP协议包里会记录所有的中转步骤,对于主叫和被叫双方是透明的。

点对点直接通信都绕不开一个麻烦,就是NAT。通过NAT,多个内网ip可以用同一个公网ip向外发数据,如果要接收的数据使用同一个tcp链接,那么NAT网关都有办法处理,这就是为什么我们通过NAT上网并不会有什么不同。但是,如果外网用户要主动建立一个到内网用户的链接,麻烦就来了。由于WiFi用户一般都要经过NAT,这就更要妥善处理了。

为此,Apple引用了三个标准:

  • STUN (Session Traversal Utilities for NAT) IETF标准,定义会话如何跨越多个不同类型的NAT
  • TURN (Traversal Using Relay NAT) IETF标准,让NAT后面的客户端可以向公网服务器一样接收外部请求
  • ICE (Interactive Connectivity Establishment) IETF标准,简化穿透NAT防火墙建立连接

facetime_tech_terms_on_wwdc10