有关堆栈溢出(in vs 2005)的读书笔记--堆栈中 申请大数组

    部分原创

     

    66下一步

    Vs 堆栈 理论修改的上限是多少

    问题2: 全局变量去 最大的上限是多少?

    堆栈(休养版本测试)

    2012年3月31日17:31:27 3月

     

     

    clip_image001

     

    clip_image002

     

    clip_image003

    10^5 10^6数组,导致vs…

    当前:搭好脚手架。

     

    改进: 修改vs系数。(byte 为单位i

    改进二: 细化 时间粒度。

     

     

    以上是我在项目汇总的修改。下面是阅读笔记

     

     

     

     

     

    test dword ptr [eax],eax ; probe page.

    2010年05月18日 星期二 20:19

    局部数组变量定义超过所分配的最大空间

    -----------------------------------

    Posts Tagged 变量

    局部数组变量定义所分配的最大空间为多少?如何设置大小

    有两个程序

    A:

    1. #include "stdafx.h"
    2. int _tmain(int argc, _TCHAR* argv[])
    3. {
    4. int nArray[256000] = {0};
    5. nArray[1] = 5;
    6. printf("array 1 is %d",nArray[1]);
    7. return 0;
    8. }

    B:

    1. #include "stdafx.h"
    2. int _tmain(int argc, _TCHAR* argv[])
    3. {
    4. int nArray[260000] = {0};

      //66 大于 1m

    5. nArray[1] = 5;
    6. printf("array 1 is %d",nArray[1]);
    7. return 0;
    8. }

     

    大家通过运行可以发现,A是可以正常运行的,B虽然编译通过了,可是当运行时就会弹出错误

    错误的原因,就是栈溢出

     

    局部变量的申请空间是存放于栈中,windows里默认栈内存是1M

    所以当申请空间大于1M时就会出现溢出错误

    通过debug就会进入以下文件chkask.asm

    page ,132

    title chkstk – C stack checking routine

    ;***

    ;chkstk.asm – C stack checking routine

    ;

    ; Copyright (c) Microsoft Corporation. All rights reserved.

    ;

    ;Purpose:

    ; Provides support for automatic stack checking in C procedures

    ; when stack checking is enabled.

    ;

    ;*******************************************************************************

    .xlist

    include cruntime.inc

    .list

    ; size of a page of memory

    _PAGESIZE_ equ 1000h

    CODESEG

    page

    ;***

    ;_chkstk – check stack upon procedure entry

    ;

    ;Purpose:

    ; Provide stack checking on procedure entry. Method is to simply probe

    ; each page of memory required for the stack in descending order. This

    ; causes the necessary pages of memory to be allocated via the guard

    ; page scheme, if possible. In the event of failure, the OS raises the

    ; _XCPT_UNABLE_TO_GROW_STACK exception.

    ;

    ; NOTE: Currently, the (EAX < _PAGESIZE_) code path falls through

    ; to the "lastpage" label of the (EAX >= _PAGESIZE_) code path. This

    ; is small; a minor speed optimization would be to special case

    ; this up top. This would avoid the painful save/restore of

    ; ecx and would shorten the code path by 4-6 instructions.

    ;

    ;Entry:

    ; EAX = size of local frame

    ;

    ;Exit:

    ; ESP = new stackframe, if successful

    ;

    ;Uses:

    ; EAX

    ;

    ;Exceptions:

    ; _XCPT_GUARD_PAGE_VIOLATION – May be raised on a page probe. NEVER TRAP

    ; THIS!!!! It is used by the OS to grow the

    ; stack on demand.

    ; _XCPT_UNABLE_TO_GROW_STACK – The stack cannot be grown. More precisely,

    ; the attempt by the OS memory manager to

    ; allocate another guard page in response

    ; to a _XCPT_GUARD_PAGE_VIOLATION has

    ; failed.

    ;

    ;*******************************************************************************

    public _alloca_probe

    _chkstk proc

    _alloca_probe = _chkstk

    push ecx

    ; Calculate new TOS.

    lea ecx, [esp] + 8 – 4 ; TOS before entering function + size for ret value

    sub ecx, eax ; new TOS

    ; Handle allocation size that results in wraparound.

    ; Wraparound will result in StackOverflow exception.

    sbb eax, eax ; 0 if CF==0, ~0 if CF==1

    not eax ; ~0 if TOS did not wrapped around, 0 otherwise

    and ecx, eax ; set to 0 if wraparound

    mov eax, esp ; current TOS

    and eax, not ( _PAGESIZE_ – 1) ; Round down to current page boundary

    cs10:

    cmp ecx, eax ; Is new TOS

    jb short cs20 ; in probed page?

    mov eax, ecx ; yes.

    pop ecx

    xchg esp, eax ; update esp

    mov eax, dword ptr [eax] ; get return address

    mov dword ptr [esp], eax ; and put it at new TOS

    ret

    ; Find next lower page and probe

    cs20:

    sub eax, _PAGESIZE_ ; decrease by PAGESIZE

    test dword ptr [eax],eax ; probe page.

     

    jmp short cs10

    _chkstk endp

    end

     

    提示栈溢出

    所以解决此问题的方法就是扩大栈空间的大小

    方法为

    项目->属性->链接器->系统->堆栈保留大小

    注:这里填的是字节数

    如果你想把他扩大为2M的话,

    1024*1024*2 = 2097152

    然后再编译运行的话A,B就都可以通过了

     

    源文档 <http://hi.baidu.com/linzch/blog/item/e5107ff0a6cf6ccf7831aa02.html>

     

posted @ 2012-03-31 17:32  os66  阅读(839)  评论(0编辑  收藏  举报