Не удается найти функцию (с оператором overflow) в стеке - PullRequest
1 голос
/ 23 мая 2011

Пожалуйста, извините, если этот вопрос задавался несколько раз, но я застрял на нем некоторое время.
Вот функция, которая имеет код переполнения стека. при отладке, когда я только что вошел в функцию, я вижу функцию в стеке ... но как только я перехожу в функцию, происходит переполнение, и тогда я не вижу имя функции в стеке.

void CCrashMeDlg::OnBnClicked_StackOverflow()
{
    int a = 10;
    a = a+10;
    BYTE bTemp[OneKilo * 1024];    
    bTemp[0] = 0;
}

Мои вопросы:

  1. Почему функция выходит из стека после переполнения. (Я вижу другие функции).

  2. если я не знаю код или если код очень большой, как я точно определю функцию, где происходит переполнение?

вот стек после переполнения.

0034f318 0129d640 CrashMe! _Chkstk + 0x27 [f: \ dd \ vctools \ crt_bld \ SELF_X86 \ crt \ src \ INTEL \ chkstk.asm @ 99]

0034f328 0129d84f CrashMe! _AfxDispatchCmdMsg + 0x45 [f: \ dd \ vctools \ vc7libs \ ship \ atlmfc \ src \ mfc \ cmdtarg.cpp @ 82]

0034f358 01293abe CrashMe! CCmdTarget :: OnCmdMsg + 0x11c [f: \ dd \ vctools \ vc7libs \ ship \ atlmfc \ src \ mfc \ cmdtarg.cpp @ 381]

0034f37c 0129a651 CrashMe! CDialog :: OnCmdMsg + 0x1d [f: \ dd \ vctools \ vc7libs \ ship \ atlmfc \ src \ mfc \ dlgcore.cpp @ 87]

0034f3cc 0129b2d3 CrashMe! CWnd :: OnCommand + 0x92 [f: \ dd \ vctools \ vc7libs \ ship \ atlmfc \ src \ mfc \ wincore.cpp @ 2675]

0034f488 01295c91 CrashMe! CWnd :: OnWndMsg + 0x39 [f: \ dd \ vctools \ vc7libs \ ship \ atlmfc \ src \ mfc \ wincore.cpp @ 2081]

0034f4a8 01299673 CrashMe! CWnd :: WindowProc + 0x24 [f: \ dd \ vctools \ vc7libs \ ship \ atlmfc \ src \ mfc \ wincore.cpp @ 2067]

0034f51c 01299702 CrashMe! AfxCallWndProc + 0xac [f: \ dd \ vctools \ vc7libs \ ship \ atlmfc \ src \ mfc \ wincore.cpp @ 248]

0034f53c 75cc62fa CrashMe! AfxWndProc + 0x36 [f: \ dd \ vctools \ vc7libs \ ship \ atlmfc \ src \ mfc \ wincore.cpp @ 410]

0034f568 75cc6d3a USER32! InternalCallWinProc + 0x23 [d: \ w7rtm \ windows \ core \ ntuser \ client \ i386 \ callproc.asm @ 106]

0034f5e0 75cc965e USER32! UserCallWinProcCheckWow + 0x109 [d: \ w7rtm \ windows \ core \ ntuser \ client \ clmsg.c @ 163]

0034f624 75cc96c5 USER32! SendMessageWorker + 0x581 [d: \ w7rtm \ windows \ core \ ntuser \ client \ clmsg.c @ 717]

0034f648 71bc4601 USER32! SendMessageW + 0x7f [d: \ w7rtm \ windows \ core \ ntuser \ client \ cltxt.h @ 795]

0034f668 71bc4663 COMCTL32! Button_NotifyParent + 0x3d [d: \ w7rtm \ shell \ comctl32 \ v6 \ button.cpp @ 2322]

0034f684 71bc44ed COMCTL32! Button_ReleaseCapture + 0x113 [d: \ w7rtm \ shell \ comctl32 \ v6 \ button.cpp @ 2424]

0034f6e4 75cc62fa COMCTL32! Button_WndProc + 0xa18 [d: \ w7rtm \ shell \ comctl32 \ v6 \ button.cpp @ 4934]

0034f710 75cc6d3a USER32! InternalCallWinProc + 0x23 [d: \ w7rtm \ windows \ core \ ntuser \ client \ i386 \ callproc.asm @ 106]

0034f788 75cc77c4 USER32! UserCallWinProcCheckWow + 0x109 [d: \ w7rtm \ windows \ core \ ntuser \ client \ clmsg.c @ 163]

0034f7e8 75cc788a USER32! DispatchMessageWorker + 0x3bc [d: \ w7rtm \ windows \ core \ ntuser \ client \ clmsg.c @ 2591]

0034f7f8 75cec81f USER32! DispatchMessageW + 0xf [d: \ w7rtm \ windows \ core \ ntuser \ client \ cltxt.h @ 999]

0034f824 0129c82e USER32! IsDialogMessageW + 0x5f6 [d: \ w7rtm \ windows \ core \ ntuser \ client \ dlgmgr2.c @ 659]

0034f838 01296ba0 CrashMe! CWnd :: IsDialogMessageW + 0x32 [f: \ dd \ vctools \ vc7libs \ ship \ atlmfc \ src \ mfc \ winocc.cpp @ 197]

0034f844 01293a9b CrashMe! CWnd :: PreTranslateInput + 0x2d [f: \ dd \ vctools \ vc7libs \ ship \ atlmfc \ src \ mfc \ wincore.cpp @ 4659]

0034f858 01299144 CrashMe! CDialog :: PreTranslateMessage + 0xa3 [f: \ dd \ vctools \ vc7libs \ ship \ atlmfc \ src \ mfc \ dlgcore.cpp @ 81]

0034f86c 012a06f2 CrashMe! CWnd :: WalkPreTranslateTree + 0x23 [f: \ dd \ vctools \ vc7libs \ ship \ atlmfc \ src \ mfc \ wincore.cpp @ 3258]

0034f884 012a08dd CrashMe! AfxInternalPreTranslateMessage + 0x41 [f: \ dd \ vctools \ vc7libs \ ship \ atlmfc \ src \ mfc \ thrdcore.cpp @ 233]

034-я ​​мультимедиа: переводы на 0,70 млн.[f: \ dd \ vctools \ vc7libs \ ship \ atlmfc \ src \ mfc \ thrdcore.cpp @ 777]

0034f89c 012a092d CrashMe! AfxPreTranslateMessage + 0x19 [f: \ dd \ vctomc \ ship \ vc\ src \ mfc \ thrdcore.cpp @ 255]

0034f8ac 0129818e CrashMe! AfxInternalPumpMessage + 0x2d [f: \ dd \ vctools \ vc7libs \ ship \ atlmfc \ src \ mfc \ 10768pp]*

0034f8d4 012941d6 CrashMe! CWnd :: RunModalLoop + 0xc5 [f: \ dd \ vctools \ vc7libs \ ship \ atlmfc \ src \ mfc \ wincore.cpp @ 4714]

0034f920 CrashM3: 83453: DoModal + 0x130 [f: \ dd \ vctools \ vc7libs \ ship \ atlmfc \ src \ mfc \ dlgcore.cpp @ 638]

0034fa20 01453987 CrashMe! CCrashMeApp :: InitInstance + 0x8f \:windbg \ crashme \ crashme \ crashme.cpp @ 64]

0034fa34 01424bc6 CrashMe! AfxWinMain + 0x48 [f: \ dd \ vctools \ vc7libs \ ship \ atlmfc \ src \ mfc \ winmain.cpp @ 37]

0034fac4 76d533ca CrashMe! __tmainCRTStartup + 0x11a [f: \ dd \ vctools \ crt_bld \ self_x86 \ crt \ src \ crt0.c @ 275]

0034fread0 77thread3232+ 0xe [d: \ w7rtm \ base \ win32 \ client \ thread.c @ 65]

0034fb10 77ce9ea5 ntdll! __ RtlUserThreadStart + 0x70 [d: \ w7rtm \ minkernel \ ntos \ rtl \ rtlexec.c @ 3188]

0034fb28 00000000 ntdll! _RtlUserThreadStart + 0x1b [d: \ w7rtm \ minkernel \ ntos \ rtl \ rtlexec.c @ 3116]

Ответы [ 3 ]

2 голосов
/ 23 мая 2011

Переполнение стека произойдет, когда программа попытается выделить огромную переменную на основе стека. Когда вы в первый раз входите в функцию, программный счетчик войдет в функцию, но пока не выполнит ее (включая инициализацию и распределение переменных стека). Однако, как только вы зайдете еще раз, он назначит переменные стека с помощью кода операции:

sub esp, xxx; //xxx is the size of the stack variable

Если результат esp-xxx находится за пределами страницы стековой памяти, он вызовет переполнение стека. Поскольку он будет выделять переменную стека, как только вы перейдете во второй раз, вы сразу поймете, что допустили ошибку в объявлении переменной.

Решением для этого будет либо:

  1. увеличение размера стека (Настройки проекта-> Линкер-> Система-> Размер стека)
  2. выделить переменную в куче.

Переполнение стека также произойдет, если вы рекурсивно вызываете слишком много раз. Большинство функций требуют некоторого временного хранения в стеке, и если вы попытаетесь выделить это слишком много раз, оно выйдет за пределы памяти. Известным примером этого может быть функция, которая рекурсивно вызывает себя, чтобы найти последовательность Фибоначчи. Когда n превышает 100000 ~, оно обычно (при условии, что размер стека равен 1 МБ, что является размером VS по умолчанию) вызывает переполнение стека.

Единственным решением для этого было бы увеличение размера стека.

0 голосов
/ 23 мая 2011

_chkstk не устанавливает цепочку ebp и изменяет кадр стека, что может привести к тому, что отладчик не сможет правильно размотать стек.

Если вы разберете _chkstk, вы можете найти, где хранится обратный адрес.В приведенном ниже примере он находится в регистре ecx.

0:000> u ntdll!_chkstk
ntdll!_chkstk:
778fad68 51              push    ecx
778fad69 8d4c2404        lea     ecx,[esp+4]
778fad6d 2bc8            sub     ecx,eax
778fad6f 1bc0            sbb     eax,eax
778fad71 f7d0            not     eax
778fad73 23c8            and     ecx,eax
778fad75 8bc4            mov     eax,esp
778fad77 2500f0ffff      and     eax,0FFFFF000h
0:000>
0 голосов
/ 23 мая 2011

Я думаю, это потому, что следующая строка выделяет много памяти в стеке:

 BYTE bTemp[OneKilo * 1024];

Попробуйте выделить ваши данные в куче:

 BYTE *bTemp = new Byte[OneKilo * 1024];

не забудьте потом освободить память

...