1

このエラーに遭遇しましたがかなり人気があります

この問題はかなりややこしいです。どの変数が正しく返されないかを把握しようとしています。この問題は、VC6 プロジェクトを VS 2012 に移植しているときに発見されました。ここで起こることは、レコード セットが DB から取得され、XML に変換されることです。

CGenAction GenAct(lUserId, O_ALARM, A_GET_TREE, ppALResult)
{
    try
    {
        if (GenAct.BeginAction())
        {
            checkuserPremission(info);

            Result Res;
            Dynaset DynaSet;

            if (type.GetRecordSet(UserId, DynaSet, Res)) {
                turnToXml(DynaSet,Res.m_bstrXMLString);
            }

            returnToUI(Res);
        }
    }
}

このタイプのバグを知る前に、次のようにして、スタックの代わりにヒープ内に配置しようResとしました。DynaSet

static Result * ResPtr = NULL;

if(ResPtr != NULL)
{
    delete ResPtr;           
}

ResPtr = new Result();

これは問題を解決しませんでした。次の変数の周りのスタックが壊れています: ResDynaSetさらに絞り込んで、すぐに質問を更新します。

4

1 に答える 1

3

これは非常に信頼性の高い診断ですが、VC6 にはありませんでした。誤った警告の可能性はゼロです。移植する前に、この問題がコードベースに存在していた可能性があることに注意してください。警告されているバグは非常に深刻なものであり、通常、助けなしに診断することは非常に困難です。ただし、致命的な問題である必要はありません。コード内に長い間潜んでいる可能性があります。突然飛び出し、非常に無害に見えるコード変更で大混乱をもたらすだけです。リリース ビルド設定を使用してプログラムを再ビルドするだけで十分な場合があり、問題の診断がさらに難しくなります。

あなたのコード スニペットは不透明すぎて理由を示唆できません。文書化されていない関数が原因である可能性があります。診断がどのように機能するかを説明するだけなので、デバッグを試してみることができます。

/RTC デバッグ オプションを使用すると、コンパイラはローカル変数をスタック フレームに割り当て、変数間にスペースを確保します。そして、それらのスペースを識別するテーブルを生成します。関数のエントリで、これらのスペースは値 0xcc で埋められます。関数の終了時に、テーブルをウォークし、それらのスペースにまだ 0xcc が含まれているかどうかをチェックするデバッグ関数を実行します。そうでない場合は、コードが決して触れてはならないスタック フレームの場所に書き込みを行っているという、非常に信頼できる兆候を示しています。スタック バッファ オーバーフローは 1 つの可能性ですが、他の可能性もあります。

それをデバッグする方法は、Debug + Windows + Memory + Memory 1 ウィンドウを使用することです。関数の最初のステートメントにブレークポイントを設定します。ヒットしたら、アドレスボックスにEBPを入れてページアップをヒットします(スタックがダウンすることに注意してください)。スタック フレーム内のバイトを表示しているため、通常は 4 バイト ビューに切り替えるのが最適です。ローカル変数と表示される値を一致させてみてください。変数間のスペースを埋める 0xcc 値も表示されます。デバッガーの StepOver コマンドを使用して、ステップ実行を開始します。スタック フレームの変更された値は赤で表示されます。赤色で以前に 0xcc が含まれていたものを探してみてください。

これで、攻撃されたバイトのアドレスがわかりました。再起動し、データ ブレークポイントを使用して、そのバイトを破壊したステートメントでデバッガーを停止させます。

于 2013-04-24T12:52:58.347 に答える