2016-09-30 26 views
2

Apple生成这些崩溃日志,我的线程0崩溃了,但这个问题不是这个问题。这是一般性问题,我想知道如何在碰撞分析中使用这些处理器寄存器值?他们如何帮助你调查你的崩溃?唯一出现在我脑海的是如果任何一个寄存器都有NULL指针,如下面的rcx,它提供了一个关于代码中可能的空指针解引用的想法,那是正确的假设吗?崩溃报告中的CPU寄存器地址如何在分析中有用?

Thread 0 crashed with X86 Thread State (64-bit): 
    rax: 0x00000001046e17a0 rbx: 0x00000001043665f0 rcx: 0x0000000000000000 rdx: 0x00000001046e14f0 
    rdi: 0x00000001046e14e0 rsi: 0x00000001046314e8 rbp: 0x00007fff5b89f890 rsp: 0x00007fff5b89f7e0 
    r8: 0x00007fff686a7690 r9: 0x0000000000000250 r10: 0x00007fffa2478201 r11: 0x000000000009ea18 
    r12: 0x00000001046b11d8 r13: 0x00007fff686a75c8 r14: 0x00007fff686ae638 r15: 0x0000000000000000 
    rip: 0x00000001043601be rfl: 0x0000000000010206 cr2: 0x0000000000000060 

Logical CPU:  0 
Error Code:  0x00000004 
Trap Number:  14 
+0

他们以各种方式帮助;事实上,你可以看到存储器地址或寄存器的值是多少...... –

+0

@ l'L'l那是真的,但是你有什么方法使用它? – PnotNP

回答

3

您可以使用寄存器RIP(指令指针)来确定失败的机器指令。我不确定GDB是否可以在Mac OSx上运行,但是在Linux中可以使用GDB(GNU Debugger),然后分析汇编指令以找到产生错误的确切指令。此外,寄存器RBP(帧指针)和RSP(堆栈指针)分别指向堆栈的底部和顶部。了解所有这些,您可以准确查看堆栈在崩溃时的内容以及哪条指令导致崩溃。

+0

OS X用于使用gdb,但是,现在lldb是标准的。 –

+0

'-fomit-frame-pointer'在几年前就已经默认(即使是32位代码),所以RBP只是另一个寄存器(如RBX或R12-R15),而不是帧指针。这种堆栈展开需要元数据(来自'.eh_frame'部分)和堆栈内存的内容,所以如果你有一个核心转储,你可以得到它。 –

0

除了@nrabbit表示的内容,您还可以使用寄存器来了解函数的某些参数的值是什么以及函数调用的结果是什么,如果您知道代码的调用约定。 Here are some examples of Intel calling conventions。例如,eax寄存器通常在32位程序中保存一个函数结果。

+0

只有当您知道崩溃发生在函数CALL或RET指令时。在函数内部,这些寄存器都是暂时的暂存空间,直到eax的最终修改产生返回值。函数也修改它们的arg寄存器。所以你只需要在崩溃位置看看asm就可以知道对于涉及到的C变量意味着什么。 **如果不仔细查看围绕RIP值的代码的asm,没有什么用处。 –