共用方式為


偵錯機器碼常見問題

如何在 Visual Studio 調試程式外部執行程式時偵錯存取違規?

Set the Just-in-time debugging option and run your program stand-alone until the access violation occurs. Then, in the Access Violation dialog box, you can click Cancel to start the debugger.

如何偵錯C++存取違規?

如果您在取值多個指標的程式代碼行上取得存取違規,則很難找出導致存取違規的指標。 在 Visual Studio 中,例外狀況對話框會明確命名導致存取違規的指標。

例如,假設有下列程序代碼,您應該會收到存取違規:

#include <iostream>
using namespace std;

class ClassC {
public:
  void printHello() {
    cout << "hello world";
  }
};

class ClassB {
public:
  ClassC* C;
  ClassB() {
    C = new ClassC();
  }
};

class ClassA {
public:
  ClassB* B;
  ClassA() {
    // Uncomment to fix
    // B = new ClassB();
  }
};

int main() {
  ClassA* A = new ClassA();
  A->B->C->printHello();

}

如果您在 Visual Studio 中執行此程式代碼,您應該會看到下列例外狀況對話框:

Microsoft Visual Studio 例外狀況對話框的螢幕快照,其中顯示 'A-B> 為 nullptr' 的讀取存取違規。已選取 [中斷] 按鈕。

如果您無法判斷指標為何造成存取違規,請追蹤程序代碼,以確定造成問題的指標已正確指派。 If it is passed as a parameter, make sure that it is passed correctly, and you aren't accidentally creating a shallow copy. 然後,藉由為有問題的指標建立數據斷點,以確定它不會在程式中的其他地方修改,以確認這些值不會意外變更於程式中的某處。 For more information about data breakpoints, see the data breakpoint section in Using Breakpoints.

如何找出我的指標是否損毀了記憶體位址?

檢查堆積損毀。 大部分的記憶體損毀都是因為堆積損毀。 請嘗試使用全域旗標公用程式 (gflags.exe) 或 pageheap.exe。 請參閱 GFlags 和 PageHeap

若要尋找修改記憶體位址的位置:

  1. 在 0x00408000 設定數據斷點。 請參閱設定數據變更斷點 (僅限原生C++)。

  2. When you hit the breakpoint, use the Memory window to view memory contents starting at 0x00408000. For more information, see Memory Windows.

如何找出誰傳遞錯誤的參數值?

若要解決此問題:

  1. 在函式開頭設定位置斷點。

  2. Right-click the breakpoint and select Condition.

  3. In the Breakpoint Condition dialog box, click on the Condition check box. See Advanced Breakpoints.

  4. 在文字框中輸入表示式,例如 Var==3,其中 Var 是包含錯誤值的參數名稱,而 3 是傳遞至錯誤的值。

  5. Select the is True radio button, and click the OK button.

  6. 現在再次執行程式。 當 參數具有 值 3Var,斷點會導致程式在函式的開頭停止。

  7. 使用 [呼叫堆棧] 視窗來尋找呼叫函式,並流覽至其原始程式碼。 如需詳細資訊,請參閱 如何:使用呼叫堆疊視窗

呼叫函式數百次時,如何知道哪個呼叫失敗?

範例:我的程式在對特定函式的呼叫時失敗。 CnvtV 程式可能會在失敗前呼叫該函式數百次。 如果我在 上 CnvtV設定位置斷點,則程式會在每次呼叫該函式時停止,而且我不想這麼做。 我不知道什麼條件導致呼叫失敗,所以我無法設定條件斷點。 我該怎麼做?

You can set a breakpoint on the function with the Hit Count field to a value so high that it will never be reached. In this case, because you believe the function CnvtV is called a couple hundred times, you might set Hit Count to 1000 or more. 然後執行程式,並等候呼叫失敗。 當失敗時,請開啟 [斷點] 視窗,並查看斷點清單。 您設定的 CnvtV 斷點隨即出現,後面接著剩餘的點擊計數和反覆項目數目:

CnvtV(int) (no condition) when hit count is equal to 1000 (currently 101)

您現在知道函式在101話叫失敗。 如果您重設命中計數為 101 的斷點,並再次執行程式,程式會在呼叫導致程式失敗時停止 CnvtV

我可以在哪裡查閱 Win32 錯誤碼?

WINERROR.H in the INCLUDE directory of your default system installation contains the error code definitions for the Win32 API functions.

You can look up an error code by typing the code in the Watch window or the QuickWatch dialog box. For example:

0x80000004,hr

如何在逐步執行應用程式時保持專注?

範例:我的程式有窗口啟用問題。 使用調試程式逐步執行程式會干擾我重現問題的能力,因為我的程式會持續失去焦點。 是否有任何方法可以避免失去焦點?

如果您有第二部計算機,請使用遠端偵錯。 您可以在主機上執行調試程式時,在遠端電腦上作程式。 如需詳細資訊,請參閱 如何:選取遠端計算機

如何偵錯 Windows API 函式?

若要在已載入 NT 符號的 Windows API 函式上設定斷點:

  • In the function breakpoint, enter the function name together with the name of the DLL where the function resides (see the context operator). 在 32 位程式代碼中,使用函式名稱的裝飾形式。 To set a breakpoint on MessageBeep, for example, you must enter the following.

    {,,USER32.DLL}_MessageBeep@4
    

    若要取得裝飾名稱,請參閱 檢視裝飾名稱

    您可以測試裝飾的名稱,並在反組譯碼中檢視它。 在 Visual Studio 調試程式的函式上暫停時,以滑鼠右鍵按兩下程式代碼編輯器中的函式,或呼叫堆疊視窗,然後選擇 [移至反組譯碼]。

  • 在 64 位程式代碼中,您可以使用未編碼的名稱。

    {,,USER32.DLL}MessageBeep
    

Next steps

您可以使用下列連結深入瞭解 Visual Studio 中的機器碼偵錯: