繁体   English   中英

SEGFAULT写入堆栈变量

[英]SEGFAULT on writing to stack variable

由于简单的代码,我在ARM linux平台上发生了非常奇怪的崩溃。 问题是它很少(一天一次)复制,而另一个问题是它实际上无法崩溃。

让我们从C ++代码开始。 线程函数可以做到这一点:

    event_obj events[EVENTS_MAX]; // EVENTS_MAX = 32
    int num = 0;
    m_engine->getEvents(events, &num);

engine是指向基础抽象类的指针,该基础抽象类目前只有一个实现。 getEvents是纯虚拟方法。

某些更改后的getEvents执行此操作

int engine::getEvents(event_obj*, int* num)
{
    if (num != nullptr)
    {
        *num = 0; // SEGMENTATION FAULT
    }
    return 1; // ok
}

尝试在num中存储0时发生SEGFAULT。 首先,我认为这是堆栈损坏,但是在检查生成的汇编代码后,似乎这里没有任何内容存储在堆栈中。 该方法甚至没有生成堆栈保护(启用了-fstack-protector-strong),两个参数都存储在寄存器r1和r2中。 让我们看一下函数调用的代码:

        event_obj events[EVENTS_MAX];
        int num = 0;
   236f8:       2300            movs    r3, #0
   236fa:       ac06            add     r4, sp, #24
   236fc:       9306            str     r3, [sp, #24]
        m_engine->getEvents(events, &num);
   236fe:       6803            ldr     r3, [r0, #0]
   23700:       691b            ldr     r3, [r3, #16]
   23702:       4622            mov     r2, r4
   23704:       a90c            add     r1, sp, #48     ; 0x30
   23706:       4798            blx     r3

以及函数本身的代码:

int engine::getEvents(event_obj*, int* num)
{
    if (num != nullptr)
   251f8:       4613            mov     r3, r2
   251fa:       b10a            cbz     r2, 25200 <_Z18engine_thread_funcPv+0x9e0>
    {
        *num = 0;
   251fc:       2200            movs    r2, #0
   251fe:       601a            str     r2, [r3, #0]
    }
    return 1; // ok
}
   25200:       2001            movs    r0, #1
   25202:       4770            bx      lr
    return 1; // ok
}

从生成的代码中可以看到,指针放置在r1r2寄存器中。

   23702:       4622            mov     r2, r4
   23704:       a90c            add     r1, sp, #48     ; 0x30

即使堆栈被破坏,它也可能破坏num变量的值,但是如何破坏寄存器中的指针呢? 同样从崩溃日志中,我可以看到LR地址是错误的。

CRASH信号11分段故障地址0xf0000000 PC 0x251fe LR 0x6c3c533c

从这里我唯一看不到的是跳转的地址(blx r3),因为被调用的方法是虚拟的。 我有一个非常不可能的假设,它没有跳到虚拟方法主体的第一行,而是跳到了该行之前的几行并损坏了寄存器,但是我不知道这怎么可能。 即使更改代码,它也总是在同一行崩溃。 真奇怪

有人可以建议尝试吗? 有任何想法吗?

提前致谢。

发生故障是因为引擎不再有效。 包含引擎的方法可能已被释放-即,您的线程内存已消失。 因此,engine-getevents在内存中甚至无效。 代码中其他地方发生了什么,线程应该已经停止运行-并退出了。 他们没有。 这很像对正在退出的应用程序的回调。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM