6

MSVC++ デバッガーで、1 つの関数にブレークポイントを作成することはできますか? その条件は、他のスタック フレームのローカル変数に依存しますか? ある関数で条件付きブレークポイントを作成していることがよくあります。そのブレークポイントがヒットすると、別のブレークポイントを有効にして (現在の関数呼び出しを終了する前に発生すると予想されます)、続行します。時間がかかり、エラーが発生しやすくなります。

私が過去に取ったアプローチの 1 つは、問題の変数をグローバルに書き込み、そのグローバルを条件として使用することです。ただし、これには再コンパイルが必要であり、マルチスレッド コードでは機能しません。

4

1 に答える 1

6

はい、技術的に可能です。大した喜びではありませんが、他のスタック フレームのローカル変数の値を取得するには、ポインターを逆参照するようにデバッガーに指示する必要があります。

簡単な例:

#include "stdafx.h"
#include <iostream>

void foo() {
    for (int ix = 0; ix < 5; ++ix) {
        std::cout << ix << " ";                 // <=== Conditional breakpoint here
    }
}

void bar() {
    for (int jx = 0; jx < 5; ++jx) {
        std::cout << jx << ": ";                // <=== Start with a breakpoint here
        foo();
        std::cout << std::endl;
    }
}

int _tmain(int argc, _TCHAR* argv[])
{
    bar();
    return 0;
}

最初に、条件を設定する変数のアドレスを取得する必要があります。bar() の指示行にブレークポイントを設定します。ヒットしたら、値を評価&jxしてコピーします。

その値を使用して、条件付きブレークポイントを設定します。私が使用した:

  *(int*)0x0073fbc8 == 2 && ix == 3

0x0073fbc8 は、最初のブレークポイントで取得した値です。または、ベースポインターレジスターから相対的にすることもできます。無条件のブレークポイントを設定し、ヒットしたら Debug + Windows + Registers を使用して EBP 値を確認します。&jx 値からそれを引きます。私が使用した:

  *(int*)(ebp+0xd8) == 2 && ix == 3

どちらもうまくいきました。デバッグ ビルドでは ASLR をオフにして、これらのアドレスが実行ごとに再現可能であることを期待することに注意してください。Project + Properties、Linker、Advanced、Randomized Base Address = No.

于 2014-05-13T22:12:16.300 に答える