用戶使用我們的framework,遇到了crash双炕,反饋了下面的調(diào)用堆棧袖肥。
2016-08-06 19:36:33.390 FxxxxxxxxxxxGame[9647:2085565] Uncaught exception: NSRangeException: *** -[__NSArrayM insertObject:atIndex:]: index 1 beyond bounds for empty array
(
0 CoreFoundation 0x000000018247edc8 <redacted> + 148
1 libobjc.A.dylib 0x0000000181ae3f80 objc_exception_throw + 56
2 CoreFoundation 0x0000000182362708 CFStringConvertNSStringEncodingToEncoding + 0
3 FxxxxxxxxxxxGame 0x00000001003fea6c -[txhw264encoder doencoder:withDataLen:withFrameIndex:withSyncId:TimeStamp:] + 964
4 FxxxxxxxxxxxGame 0x00000001003d97d0 _ZN23txrtmp_hw264_ObjEncCall18objectiveCallDoDecEPhiiil + 100
5 FxxxxxxxxxxxGame 0x00000001003ff1a4 _ZN21txrtmp_hw264_Hd264Enc7DoCodecEPhiii + 48
6 FxxxxxxxxxxxGame 0x00000001003ea7c0 _ZN12CH264Encoder11EncodeFrameEiPhiijj + 684
7 FxxxxxxxxxxxGame 0x00000001003eda50 _ZN16CTXH264EncThread10threadLoopEv + 68
8 FxxxxxxxxxxxGame 0x00000001003efe0c _ZN15TXMessageThreadI16CTXH264EncThreadE11_threadLoopEPv + 80
9 libsystem_pthread.dylib 0x00000001820e3b28 <redacted> + 156
10 libsystem_pthread.dylib 0x00000001820e3a8c <redacted> + 0
11 libsystem_pthread.dylib 0x00000001820e1028 thread_start + 4
)
這個(gè)調(diào)用棧已經(jīng)精確到函數(shù)。我們拿到這個(gè)棋电,已經(jīng)知道是-[txhw264encoder doencoder:withDataLen:withFrameIndex:withSyncId:TimeStamp:]
這個(gè)函數(shù)觸發(fā)了異常茎截,但是沒有指出來(lái)具體是那一行。
能定位到函數(shù)赶盔,那是因?yàn)槲覀兊絝ramewrok的符號(hào)表有這個(gè)名字企锌;他們沒有framewrok代碼,framewrok也沒有dSYM于未,定位不到具體的某行是正常的撕攒。
現(xiàn)在我們手頭上有用這個(gè)framework編的一個(gè)Demo,以及Demo的dSYM文件(事實(shí)上是這個(gè)Demo依賴了framework烘浦,當(dāng)自動(dòng)構(gòu)建編出Demo后抖坪,同時(shí)build的framewrok就直接拿來(lái)發(fā)布了)。能不能用這個(gè)來(lái)定位呢闷叉?
理論上說(shuō)應(yīng)該是可以擦俐,因?yàn)閒ramewrok本身沒有變化,我們要的是-[txhw264encoder doencoder:withDataLen:withFrameIndex:withSyncId:TimeStamp:]
+ 964 指向的究竟是哪一行握侧,這個(gè)偏移在Demo中并沒有發(fā)生變化蚯瞧。
現(xiàn)在問(wèn)題來(lái)了,怎么知道-[txhw264encoder doencoder:withDataLen:withFrameIndex:withSyncId:TimeStamp:]
在Demo中的偏移品擎。搜索了一番后埋合,發(fā)現(xiàn)dwarfdump
這個(gè)工具可以幫忙做到
$dwarfdump --arch=arm64 --find "-[txhw264encoder doencoder:withDataLen:withFrameIndex:withSyncId:TimeStamp:]" RTMPiOSDemo.app.dSYM/Contents/Resources/DWARF/RTMPiOSDemo
----------------------------------------------------------------------
File: RTMPiOSDemo.app.dSYM/Contents/Resources/DWARF/RTMPiOSDemo (arm64)
----------------------------------------------------------------------
Searching .debug_pubnames for '-[txhw264encoder doencoder:withDataLen:withFrameIndex:withSyncId:TimeStamp:]'... 1 match:
0x0021b78b: TAG_subprogram [152] *
AT_low_pc( 0x000000010004d330 )
AT_high_pc( 0x000000010004d820 )
AT_frame_base( reg29 )
AT_object_pointer( {0x0021b7af} )
AT_name( "-[txhw264encoder doencoder:withDataLen:withFrameIndex:withSyncId:TimeStamp:]" )
AT_decl_file( "/data/rdm/projects/24662/RTMPSDK/H264/HW264_iOS/hw264encoder.m" )
AT_decl_line( 143 )
AT_prototyped( 0x01 )
AT_type( {0x0021b199} ( int ) )
AT_APPLE_optimized( 0x01 )
AT_low_pc
就是加載的偏移。用計(jì)算器手動(dòng)算一下:0x000000010004d330+960=0x10004D6F0
$atos -arch arm64 -o RTMPiOSDemo.app.dSYM/Contents/Resources/DWARF/RTMPiOSDemo 0x10004D6F0
-[txhw264encoder doencoder:withDataLen:withFrameIndex:withSyncId:TimeStamp:] (in RTMPiOSDemo) (hw264encoder.m:231)
定位到具體的行了孽查。