在取消引用寄存器(%r11)时崩溃在objc_msgSend中,但我不明白为什么

A O*_*A O 2 assembly x86-64 objective-c cpu-registers

所以我有一个有5个参数的方法.正如预期的那样,寄存器在调用之前就说明了:

$rdi: The receiver
$rsi: the selector for the method
$rdx: first arg
$rcx: second arg
$r8: third arg
$r9: fourth arg
$r10 fifth arg
Run Code Online (Sandbox Code Playgroud)

在该方法中,它首先要做的是调用另一个objective-c方法

这反过来调用objc_msgSend(见偏移+58):

MyApp`-[GTMOAuth2WindowController webView:resource:willSendRequest:redirectResponse:fromDataSource:]:
    0x10044a1a0 <+0>:   pushq  %rbp
    0x10044a1a1 <+1>:   movq   %rsp, %rbp
    0x10044a1a4 <+4>:   subq   $0x40, %rsp
    0x10044a1a8 <+8>:   movq   0x10(%rbp), %rax
    0x10044a1ac <+12>:  movq   %rdi, -0x10(%rbp)
    0x10044a1b0 <+16>:  movq   %rsi, -0x18(%rbp)
    0x10044a1b4 <+20>:  movq   %rdx, -0x20(%rbp)
    0x10044a1b8 <+24>:  movq   %rcx, -0x28(%rbp)
    0x10044a1bc <+28>:  movq   %r8, -0x30(%rbp)
    0x10044a1c0 <+32>:  movq   %r9, -0x38(%rbp)
    0x10044a1c4 <+36>:  movq   %rax, -0x40(%rbp)
    0x10044a1c8 <+40>:  movq   -0x10(%rbp), %rax
    0x10044a1cc <+44>:  movq   -0x38(%rbp), %rdx
    0x10044a1d0 <+48>:  movq   0x2ffda9(%rip), %rsi      ; "handleCookiesForResponse:"
    0x10044a1d7 <+55>:  movq   %rax, %rdi
    0x10044a1da <+58>:  callq  0x1005839a2               ; symbol stub for: objc_msgSend
Run Code Online (Sandbox Code Playgroud)

然后转到以下说明objc_msgSend:

libobjc.A.dylib`objc_msgSend:
->  0x7fff9084a0c0 <+0>:   testq  %rdi, %rdi
    0x7fff9084a0c3 <+3>:   je     0x7fff9084a140            ; <+128>
    0x7fff9084a0c6 <+6>:   testb  $0x1, %dil
    0x7fff9084a0ca <+10>:  jne    0x7fff9084a14b            ; <+139>
    0x7fff9084a0cd <+13>:  movabsq $0x7ffffffffff8, %r11
    0x7fff9084a0d7 <+23>:  andq   (%rdi), %r11
    0x7fff9084a0da <+26>:  movq   %rsi, %r10
    0x7fff9084a0dd <+29>:  andl   0x18(%r11), %r10d
Run Code Online (Sandbox Code Playgroud)

+29当cpu试图取消引用%r11寄存器时,我有时会在偏移上崩溃.

我的问题是,为什么要objc_msgSend取消引用该注册?根据作为临时寄存器的System V ABI.但它每次都被解除引用objc_msgSend,我无法弄清楚它的用途.

当存在无效指针时,我的崩溃正在发生 %r11

看起来像在+23,%rdi寄存器(指向接收器的指针)被解除引用并且andq与之相关%r11,但是我没有得到它的作用.但也许如果接收器在这里被解除分配,%r11会被垃圾填满吗?

这个理论由这个汇编来源w /评论证实

我认为它表示%r11用于isa属性
"class = self-> isa".

这意味着该对象正在被释放,因为该isa属性是垃圾

如果是这样,我怎么能防止这种情况?

if( self )在打电话之前检查是否objc_msgSend足够?

rob*_*off 5

很遗憾,您关联的网站已过期.它没有解释objc_msgSend您正在使用的确切版本.

要了解反汇编程序输出,您需要了解的是Objective-C运行时现在具有一个名为"非指针isa"的功能.该网站上的另一个页面解释了非指针isa,但我会总结一下.

从历史上看,对象的isa字段是指向对象类的指针.此指针不需要完整的64位,因为Apple的操作系统都不使用完整的64位地址空间.类地址的许多位始终为零.

非指针isa将这些位用于其他事物,而不是浪费对象的引用计数.这意味着当您需要指向类的指针时,需要将其他位设置为零以获取有效地址.计算isa & 0x7ffffffffff8会关闭(屏蔽掉)所有非指针位,因此您可以获得指向该类的有效指针...

...如果isa字段没有被破坏.如果isa字段已损坏,则会出现垃圾.如果垃圾是无效地址,则会导致崩溃.

这里发生的事情是你覆盖了包含对象的内存,这样isa字段就不再有效了.

要调试问题,请阅读有关如何查找僵尸的信息.如果这没有帮助,请观看此WWDC视频,了解如何使用地址清洁剂.