170 – thread jump使用注意

11. 四月 2019 iOS 0

 

这篇文章写在还没有写完的171-expression实用(后面会称为171)的时候。

为什么突然要写到这篇文章,因为首先会在171中写到一个WWDC中的一个例子,具体例子就不说了,因为171中后续会补充进来。

所使用的调试办法就是:tread jump --by 1跳过所要执行的这一行,然后使用expression somecode here注入一个后续执行的代码。

我在尝试自己使用这种方式调试时,如下:

picture here

具体操作就是,在点击事件处理过程中,使用jump来跳过setTitle这一行代码,来使用我的特殊值作为标记。

然后,我遇到了一个崩溃的bug:

挂在了objc_retain这个frame上。看到汇编,在Xcode10中,你需要情不自禁的使用po $arg1还有po $arg2,po $arg3,参数和调用者(arg3和arg1)都没有什么实质的进展,但是方法却显示是:release

那么,这个问题就挂在了

当你暂停的代码是最后一行时,其实往下面做1行线程跳跃,会跳出这个函数体,导致需要在函数末尾执行的一些操作紊乱,比如说release操作,autoreleasepool的push,都会因为跳出函数体而崩溃。

尝试再加入一行代码 NSLog(@”123″)

那么缺一行代码,我们最常用,对代码不会有太大影响的。肯定是NSLog了。
但是仍然是失败。错误出在“objc_msgSend”,具体的实质原因需要探究NSLog,_fastCStringContents是最终线程frame挂掉的方法。
NSLog本身就是C语言的打印,我们通过clang编译后,也是NSLog打印一个存在data区的一段字符串

所以我们不再探究NSLog内部的实现,我们知道了,现在NSLog也是不行的.

尝试加入赋值语句之类的

最后随便加了一行赋值语句,成功执行。

总结

是很好的一个跳过这行执行的方法,再配合代码注入可以很好的去验证修复bug。但是,需要我们注意的有几个地方:

  1.  在方法末尾最后一行执行jump,会有跳出当前function的bug
  2.  在if语句的判断行,不能执行jump,类似的switch的判断行。因为这些都是执行下面的先觉条件。
  3.  有人又问,先跳过再去注入一个判断条件可以么?答案是不行的,因为本身的if语句本身的结构已经被破坏了。
  4.  你可以将jump很生硬的理解为,不管上下文,直接执行下一行。