いきなり、スタックオーバーフローが – プログラミング – Home

いきなり、スタックオーバーフローが
 
通知
すべてクリア

いきなり、スタックオーバーフローが


ちゃまいえ
 ちゃまいえ
(@ちゃまいえ)
ゲスト
結合: 19年前
投稿: 33
Topic starter  

Windows 10での、Visual Studio 2005です。
プログラムが走って、C言語側のコードは全く走らず、いきなり、
int main(void){
の処で、スタックオーバーフローです。
アセンブラが走って、その最後から4行目の処で、引っ掛かりました。
メッセージは、
Edge_Det.exe の 0x004126c7 でハンドルされていない例外が発生しました:
0xC00000FD:
Stack over flow
何が悪いのでしょうか?

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


引用解決済
トピックタグ
ちゃまいえ
 ちゃまいえ
(@ちゃまいえ)
ゲスト
結合: 19年前
投稿: 33
Topic starter  

今回の現象、ある程度、解析できました。
ソースの方で、
#include<stdio.h>
#include<math.h>
#include<string.h>

#define PATH  256
#define WIDTH 600
#define HEIGHT 600

main(){
char path[PATH];
unsigned char img[WIDTH][HEIGHT][3];
となっていた処を、と、メモリの確保領域を狭くすべく、
#include<stdio.h>
#include<math.h>
#include<string.h>

#define PATH  256
#define WIDTH 450
#define HEIGHT 450

main(){
char path[PATH];
unsigned char img[WIDTH][HEIGHT][3];
に変えてみたのです。
つまり、WIDTHとHEIGHTを、それぞれ600⇒450にしてみました。
そんなら、走り始め、以前のような、
頭からの、スタックオーバーフローで、ハングする現象が消えました。
しかし、これら、2つは、画像処理する上での、
画像ファイルの横幅と高さの最高値ですので、元々のように、
出来るだけ、大きく数字は持っておきたいものです。
どうすればようのでしょうか?
int だったらば、long intなんていう指定もできたような気がするのですが、
unsigned charをいじって、何らかの解決方法は、ないでしょうか?
よろしく、お願いします。


返信引用
瀬戸っぷ
 瀬戸っぷ
(@瀬戸っぷ)
ゲスト
結合: 18年前
投稿: 178
 

>Windows 10での、Visual Studio 2005です。

アップグレードなんでしょうかね?
VS2005はWindows10ではインストールできなかったかと思いますが。
# 手持ちのVS2005Stdが使えなくなった(TT

>どうすればようのでしょうか?

ローカル変数(自動変数)は一般的にスタックから取られます。
ということで、「サイズの大きなローカル変数は使わないようにする」というのが普通な
のですが……。

・mallocなどで動的確保する。
 もちろんこの場合はポインタ使用ということになりますから、単純な三次元配列のよう
には使えません。
・グローバル変数にする。
 ちゃんと管理しないと意図しないところで変更されてしまいます。
・static変数にする。
 無難…なのかなぁ……。
・スタックのサイズを増やす。
 リンカのオプションにあります。
 が、どこまで増やせばいいのか…という問題もありますのでご注意を。
 確かVSでは規定値が1Mだったかと。


返信引用
ITO
 ITO
(@ITO)
ゲスト
結合: 22年前
投稿: 1235
 

うーーん、
600 X 600 X 3 = 1080000
1Mbyte 1048576
30424 約32Kbyteオーバーですね。

画像の場合は意外と解決しやすいですね。

顧客と最大画素数を決めて、使用メモリーを計算する。
それを
 瀬戸っぷさんの意見どうりに
  ・mallocなどで動的確保する。
 ・グローバル変数にする。
ですね。
ちなみに僕はnewを使いますね。
スタックサイズは変えないようにしたほうがいいですね。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました