• ベストアンサー

VisualC++6.0にて、コールスタックを見てもどこから来たかわからない

VisualC++6.0を使用しています。ほとんどわからないのに、都合で修正を任されています。調べながら、少~しずつなんとか進んでいますが、どうしても進めなくなりました。 繰り返し呼び出されているプロシージャ(?)があるのですが、そこの先頭でブレークして、コールスタックを見ても、呼び出し元のほうが、わけのわからない数字になっていて、プロシージャ名ではありませんでした。そこに飛んでみると、アセンブラのような処理が書いてあるだけで、さっぱりちんぷんかんぷんです。。。 このプロシージャを繰り返させている大元を探し出したいのです。 初心者で、質問の意味もわかりにくく、また、答えも書きにくいかもしれませんが。。。なにかアドバイスがありましたら、ご指導ください。m(__)m よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • neKo_deux
  • ベストアンサー率44% (5541/12319)
回答No.2

具体的なプロシージャ名を提示しては? 例えば、ダイアログに「Hello,World!」を表示するプログラムなんか、 main(){MsgBox("Hello,World!\n");} のような感じだと思いますが、表示されるダイアログの位置、右上の×ボタンの表示処理とかの処理って、特に何も書かなくてもやってくれます。 そういう処理部分が、 > わけのわからない数字になっていて、 > アセンブラのような処理が書いてあるだけで、 です。 -- そういう場合での呼び出しを避けるには、適度に実行開始して適当な所で [デバッグ]-[ブレーク] ブレークポイントを設定して、 [デバッグ]-[実行] とか。 もっともNo.1さんの指摘のようなマウスが動いた際に呼び出されるような箇所の場合、上のデバッグ操作も影響を与えてしまうので、PC2台でリモートデバッグとかが必要になります。

その他の回答 (2)

回答No.3

TRACEを使うことも有効です。 怪しげな箇所に以下を入れておき、[デバッグ]-[実行]です。 TRACE("hogehoge\n"); VCのアウトプットウィンドウに"hogehoge"と表示されます。 いろいろ原因があると思いますが、何か無限ループに陥いてスタックオーバーフローしてるかも。

  • kmb01
  • ベストアンサー率45% (63/138)
回答No.1

もし繰り返し呼ばれる関数名がOnDrawとかOnMouseMoveとかなら、それらは画面の再描画が必要なとき、マウスが動いたときに自動的に呼ばれるように登録されています。登録している部分のコードを見たいなら関数名をプロジェクト中の全ファイルに対して検索すれば(VC++6.0なら)見つかるでしょう。 しかし普通は関数名から繰り返し呼ばれる理由は推測がつきます。

関連するQ&A

  • おかしな現象が発生 問題の関数内のスタックが原因?

    VisualC++2005でプログラムを書いているのですが、おかしな現象が発生しまして、皆さんも似たような経験をされたかどうかお聞きしたいです。 C言語の関数の動作テストしているのですが、問題の関数をコールした後、通るべきプログラムを飛ばして、次の行の命令から実行されます。 具体的には、n=a();という関数がありまして、 戻ってきた位置に if (n == 0) { // ------------------ (A) printf("通過すべき場所"); } があり、デバッグの自動変数ではnは0,であるため、「通過すべき場所」が 表示されるはずですが、実行中もでバック中もここを飛ばして、次の行から動作しています。 問題のa()はコールした時はアセンブラのような画面が出てきたので、おかしいなと思ったのですが、(A)の位置にブレークポイントを置きそこまで走らせると、そこで止まり、F11でステップインさせると、飛ばして別の行へいきます。 問題のa()内のスタックが壊れているのでしょうか? もう一度a()の関数を書きなおして、中で定義している配列の大きさなど調べた方が良いのでしょうか?

  • OCXからのコールバックを繰り返すとスタック領域が不足する

    こんにちは。 いつもお世話になっております。 OCXからのコールバックが繰り返された場合に「実行時エラー28 スタック領域が不足しています。」が発生して困っています。 以下のようにOCXからのコールバックでプロシージャを再帰的に呼び出しています。 <Command1_Clickイベント> ------------------------------------------------------------------------------------- Private Sub Command1_Click() 'OnTestイベントを発生させる Test.Test End Sub ------------------------------------------------------------------------------------- <OnTestイベント> ------------------------------------------------------------------------------------- Private Sub Test_OnTest(ByVal sStatus As Long, ByVal FileName As String) Select Case sStatus Case 0 'ステータスが0になったら終了 Exit Sub Case Else '再帰的にOnTestイベントを発生させる Test.Test End Select End Sub ------------------------------------------------------------------------------------- すると、294回目でスタック領域不足が発生します。 MSDNによると「イベント連鎖」と呼ばれるものであるようですが、途中までうまくいくので何か他に原因がないかと思っています。 http://msdn2.microsoft.com/ja-JP/library/0ctsw64a.aspx 回避策などありましたらご教示下さい。 ちなみにOCXの処理としては、フォルダ内の該当ファイル名を1つずつ返すというものです。 <環境> Windows 2000, VB6.0

  • アセンブラの読み方

    お世話になります。 アセンブラを勉強しています。 下記について教えていただけないでしょうか。 よろしくお願いいたします。 1 .file 2 .data 3 var: .long 0x1234 4.text 5 .global main 6 main: 7 movb $1, %al // 値1をレジスタalに代入 8 push %eax // レジスタeaxの内容をスタックに格納 9 call IncReg // 関数呼び出し 10 pop %eax // スタックからレジスタeaxに引き出し 11 push var // 変数varの内容をスタックに格納 12 call IncReg // 関数呼び出し 13 pop %ecx // スタックからレジスタecxに引き出し 14 ret // リターン 15 IncReg: 16 movl %esp, %ebp // pushによって動いたスタックの先頭アドレスをレジスタ ebp に代入 17 movl 4(%ebp), %edx // mainから渡された eax(var) の値をレジスタ edx に代入 18 incw %edx // レジスタ edx の値を2増やす 19 movl %edx, 4(%ebp) // 2増やしたものを引数のあるスタックの場所に代入 20 ret // リターン (質問) 7 でレジスタ al に 1 を代入したのは何か意味があるのでしょうか。 17 の4(%ebp)はスタックポインタの1つ下、つまりmainから渡された引数でよろしいでしょうか。 18 の incw %edx はレジスタ edx の値を 2 増やすという意味でよろしいでしょうか。 13 でレジスタ ecx の値は 1236 になるので正しいでしょうか。

  • Cプログラミングの関数電卓のアルゴリズムについてですが、

    Cプログラミングの関数電卓のアルゴリズムについてですが、 標準入力からの文字列式を、トークンに区切り、先頭から配列型スタックに格納して、計算を行う処理を考えていて、 a-b-cという処理のアルゴリズムに困っています。 どういった解決策があるのか教えて頂けませんか?? お願いします!! フローチャートを書くほどの事でも無いと思うので、僕が考えていたアルゴリズムを、文で記載しますが、できれば、このアルゴリズムからどうすれば解決できるかを考えて頂けたらとても助かります!! 1. 別のスタックを用意して、元々のをstack1,コピー用をstack2とし、stack1のトップからstack2に格納。(スタックの構造は二次元文字型配列) この場合、cからstack2に格納される。 2. 演算子を見つけると、その前後の数字をその演算子によって処理。 この場合なら、c-bという処理。 3. 計算結果を、cが格納されていた、演算子の前に格納。 4.引き続き、この操作を繰り返す。 これを考えてたんですが、実行すると、(c-b)-aという式になり、違う答えが出てしまいます。加算ならば影響はでません。 きちんと(-c-b)+a の処理をさせるにはどうしたら良いかがわからないです。 お願いします!! ※返事が多少遅れるかもしれませんが、すみません!!

  • 戻り番地を逃がしておくの意味が分かりません

    いつもお世話になっております。独学で情報処理の勉強をしています。昨日CASLIIをキャスルツーと読むことを知ったぐらいです。「なるべく専門用語を使わないで答えてくださる方」よろしくお願いします。 基本情報午後の選択はCASLIIがいいと思って参考書を読んでみたのですが、とても難しく、ネットで検索していたら理解を深めるための記事みたいのがあったのですが、【主プログラムから副プログラムのデータの受け渡し】ということで以下のことが書かれてます。 LAD  GR1,123     ;GR1に123を格納する(主プログラムの先頭)   PUSH   0,GR1 ;123をスタックに格納する     LAD   GR2,456 ;GR2に456を格納する     PUSH   0,GR2 ;456をスタックに格納する     CALL   SUB1  ;副プログラムSUB1を呼び出す     POP   GR3    ;加算結果をスタックからGR3に取り出す        :   ;これ以降の処理は省略する  SUB1 POP   GR4   ;戻り番地を逃がしておく  ←これ!!    POP   GR1    ;GR1に456を取り出す(副プログラムの先頭)   POP   GR2   ;GR2に123を取り出す     ADDA  GR1,GR2 ;GR1とGR2の加算結果をGR1に格納する      PUSH   0,GR1 ;加算結果をスタックに格納する      PUSH   0,GR4 ;戻り番地を元通りにする  ←ここも!!     RET      ;主プログラムに戻る(副プログラムの末尾) の、戻り番地を逃がしておくが意味がよく分かりません。なので、戻り番地を元通りにするもよく分かりません。 よろしくお願いします。

  • 擬似言語のある処理について

    擬似言語についてわからないことがあります。 このプログラムはスタックを使って、実数値を10進数字に変換するプログラムです。 今回質問するのは、このプログラムの中でも数値を一桁ずつ10進数字に変換して、スタックに詰め込む部分です。 Fintは整数部分。Idxは変数。 IntはFの小数部をカットする。(つまり、整数部分だけにする処理です。) Chr[]={0,1,2,3,4,5,6,7,8,9},T (Chrは数値に対応する文字列を格納したものです。) Fint←Int(F) 繰り返し処理 Fint>0ならば ・Idx ← Fint - (Fint ÷ 10) × 10;Fintの最下位桁をIdxに取り出す。 ・Push(Chr[Idx]);最下位桁Idxに対応する数字をスタックにプッシュする ・Fint←Fint÷10;次の桁を最下位の桁にシフトする。 繰り返しで上へ 上記の「Fintの最下位桁をIdxに取り出す」という処理は たとえば、12,345という数字があったならば、12の最下位桁2を取り出すということなのだと思いますが、式に当てはめて計算すると 12-(12÷10)×10となりIdxに0という数字が格納されます。 その後に、Chrで0という数値を拾ってきて文字列0が格納されることになります。 しかし、問題文を見ると12,345という数字を変換すると12,345という文字列になっておりなぜ0?になってしまうのという話になります。 私の解釈は間違いだらけだと思いますが訂正していただけると 大変うれしいです。

  • プログラムについて。

    Private Sub btn_削除_Click() Flg_修正削除 = 2 If 整合性チェック処理 = 1 Then Exit Sub If MsgBox(\"削除してもいいですか?\" & vbNewLine & vbNewLine & \"削除したデータは復旧できません\", vbOKCancel) = vbCancel Then Exit Sub DoCmd.OpenQuery \"sp_MST_AAA情報_削除\" Call 更新後処理 Call 画面項目削除 MsgBox \"削除されました\", vbInformation End Sub これは削除ボタンを押したら削除処理がなされるイベントプロシージャーなのですが、見ていて意味が分かるのがメッセージBOXに表示される言葉だけです。他はどのような意味を持っているのでしょうか??

  • 数学の問題を教えてください(場合の数またはN進法

    場合の数?N進法? いつもご丁寧なご指導・ご助言ありがとうございます。 「以下のように、1,3,5の3種類の数字のみを使って作れる自然数を小さい順に並べた。 1,3,5,11,13,15,31,33,35… この数列において、33333は先頭から( )番目の数である」 私は場合の数の問題だと思ったのですが、友人はN進法じゃね?と言います。 N進法の考え方で解くことができますか?解けるとすれば解法をご教授下さい また、答えは242番目であっていますか? 宜しくお願いいたします。

  • フォルダー内の複数ファイル名を一括で変名するbat

    フォルダー内の複数ファイル名を一括で変名するbatを教えてください。 batは、デスクトップに配置して 処理するフォルダーをD&Dして処理させる形式をとしたいです。 以下のような形式です。  No1 aaaa bbbb [com : *********].zip を  No1 aaaa bbbb.zip に変名する。   (*******は任意の文字列) 例えば、 No1 aaaa bbbb [com : taken2110221100014].zip であれば No1 aaaa bbbb.zip に変名する。 以下が参考になりそうなので https://oshiete.goo.ne.jp/qa/9263608.html 記事中の助言を元に以下のようにコードを修正してみましたが うまく処理できませんでした。 bat(test,bat,test2.bat)のどこを再修正すれば希望の処理ができますか ? 希望は、下記ですが 「batは、デスクトップに配置して 処理するフォルダーをD&Dして処理させる形式をとしたいです。」 batを修正してもこのbatでは、D&Dで処理することは可能で無い場合は アドバイス又は他の参考なりそうなURLを紹介ください。 '------------------------------------------ rem test.bat echo off for /F "delims=" %%f in ('dir /*.mp4') do call :sub "%%f" exit /*.mp4 :sub set fname=%~1 set n=0 :loop call set c=%%fname:~%n%,1%% set /a n=n+1 if "%c%"=="" goto :EOF if "%c%"=="[com" goto break goto loop :break set /a n=n-1 set ext=%~x1 call set newname=%%fname:~0,%n%%% call set newname=%newname%%ext% if "%newname%"=="" goto :EOF if "%newname:~0,1%"=="." goto :EOF ren "%fname%" "%newname%" goto :EOF '-------------------------------------- rem bat2.bat for /F "tokens=1* delims=[com" %%F in ('dir /b *.mp4') do echo move %%F[com%%G %%F.mp4 '--------------------------------------

  • VBA、このようなケースはどうしたらよいでしょうか?

    すみません。VBA初心者なので質問がちぐはぐになるかと思いますが、よろしく お願いいたします。 Sub セル番地() Worksheets("Sheet1").Select Cells(2, 2).Select Range(Selection, Selection.End(xlDown)).Select rnum = Selection.Rows.Count - 1 MsgBox rnum End sub 上のVBAでシート1に数字入力されているセルの数を判断します。 Sub sheetcopy() For X = 3 To 100 If Cells(X, 2) <> "" Then Cells(X, 2).Copy Destination:=Worksheets("Sheet1").Cells(X + rnum, 2) ElseIf Cells(X, 2) = "" Then Exit For End If Next End sub このVBAは、選択しているシートに入っている数字をシート1へコピーするものです。 ”セル番地”で判定した変数rnumを、”sheetcopy”に記載されている変数rnum へ渡すためにはどのようにしたらよいでしょうか? 引数付きプロシージャの説明を読んでみたのですが、いまいちわかりませんでした。最終的には、各シートに入力されている数値をシート1のあいているセルへどんどんコピーさせたいのです。ひとつのプロシージャに書けば、問題なく動くのですが、見た目をすっきりさせたいと思います。 イメージとしてはこんな感じです。 sub sheetcomplete () call セル番地 Worksheets("Sheet2").Select call sheetcopy call セル番地 Worksheets("Sheet3").Select call sheetcopy ~ ~ End sub そもそも、よくわかっていないので滑稽に見えると思いますが、よろしくご指導ください。

専門家に質問してみよう