[英]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
}
從生成的代碼中可以看到,指針放置在r1
和r2
寄存器中。
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.