導致堆棧溢出的一個顯而易見的方式是獲得Segmentation fault
,將遞歸地將堆棧幀疊加到彼此的頂部,直到它繁榮。我想知道如果堆棧溢出可能發生,甚至沒有推動新的堆棧幀。如何溢出堆棧而不推送新的堆棧幀?
創建一個足夠大的陣列也可以從經驗中做到,但是還有其他可能的場景嗎?
導致堆棧溢出的一個顯而易見的方式是獲得Segmentation fault
,將遞歸地將堆棧幀疊加到彼此的頂部,直到它繁榮。我想知道如果堆棧溢出可能發生,甚至沒有推動新的堆棧幀。如何溢出堆棧而不推送新的堆棧幀?
創建一個足夠大的陣列也可以從經驗中做到,但是還有其他可能的場景嗎?
C99使用可調整大小的數組,您可以使用它並將其調整爲較大的數組。然而,這個可調整大小的陣列使用alloca
來實現。下面是UNIX ENV一個示例代碼:
#include <stdio.h>
#include <alloca.h>
#include <stdlib.h>
#include <stdbool.h>
int
main()
{
while (true)
{
void *p = alloca(32UL);
printf("new memory allocated at %p \n", p);
}
exit(EXIT_SUCCESS);
}
而且你的輸出看起來就像這樣
new memory allocated at 0xbf800a60
new memory allocated at 0xbf800a30
new memory allocated at 0xbf800a00
new memory allocated at 0xbf8009d0
new memory allocated at 0xbf8009a0
[1] 3977 segmentation fault ./a.out
alloca
是在malloc
家庭的功能,但它通過調整棧上分配的內存堆棧指針。
濫用alloca()
或_alloca()
如果你正在開發的Windows SDK/VS:
的ALLOCA()函數分配的空間大小字節在 調用者的堆棧幀。
注意_alloca()
現在被棄用,有利於_malloca()
。
從根本上說,「堆棧」只是一些內存,當ESP/EBP超出這個內存的界限時,堆棧溢出。
int x[10000000];
__asm mov esp, 0x0
您可以通過多種方式實現這一點破壞堆棧,因此噹噹前函數展開時,ESP/EBP將被設置爲垃圾:int x; memset(&x, 0, 10000000);
And coun tless其他方式...
通過聲明和使用數組比你的堆棧大小:
$ ulimit -s
8192
$
然後
int main(void)
{
volatile char bla[8192 * 1024 + 16] = {0};
}
很可能在執行時出現段錯誤。
爲什麼輸入volatile?在我的示例中爲 – 2012-04-11 09:30:22
,以避免編譯器優化它,因爲它不在程序中的其他地方使用。如果你使用'printf'打印'for'循環來打印所有元素,那麼你不需要'volatile'限定符,因爲編譯器無法優化它。 – ouah 2012-04-11 09:32:17
這將在Linux/UNIX環境中。 – 2012-04-11 09:08:09
'alloca'和VLA。 – Mat 2012-04-11 09:09:07