簡體   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