Visual Studio 디버거 외부에서 프로그램을 실행하는 경우 액세스 위반을 어떻게 디버그할 수 있나요?
Just-In-Time 디버깅 옵션을 설정하고 액세스 위반이 발생할 때까지 프로그램을 독립 실행형으로 실행합니다. 그런 다음, 액세스 위반 대화 상자에서 취소를 클릭하여 디버거를 시작할 수 있습니다.
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에서 이 코드를 실행하는 경우 다음 예외 대화 상자가 표시됩니다.
포인터가 액세스 위반을 유발한 이유를 확인할 수 없는 경우 전체 코드를 추적하여 문제를 유발한 포인터가 올바르게 할당되었는지 확인합니다. 포인터가 매개 변수로 전달된 경우 제대로 전달되었는지, 실수로 단순 복사를 만들지 않았는지 확인합니다. 그런 다음, 프로그램의 다른 곳에서 수정되지 않도록 문제가 되는 포인터에 대한 데이터 중단점을 만들어 프로그램의 어딘가에서 값이 실수로 변경되지 않는지 확인합니다. 데이터 중단점에 대한 자세한 내용은 Using Breakpoints에서 데이터 중단점 섹션을 참조하세요.
포인터가 메모리 주소를 손상시키는지 어떻게 알 수 있나요?
힙 손상을 확인합니다. 대부분의 메모리 손상은 힙 손상으로 인해 발생합니다. 전역 플래그 유틸리티(gflags.exe) 또는 pageheap.exe를 사용해 보십시오. /windows-hardware/drivers/debugger/gflags-and-pageheap을 참조하세요.
메모리 주소가 수정된 위치를 찾으려면:
0x00408000에 데이터 중단점을 설정합니다. 데이터 변경 중단점 설정(네이티브 C++만 해당)을 참조하세요.
중단점이 적중되면 메모리 창을 사용하여 0x00408000에서 시작하는 메모리 내용을 검토합니다. 자세한 내용은 메모리 창을 참조하세요.
무엇이 잘못된 매개 변수 값을 전달하는지 어떻게 알 수 있나요?
이 문제를 해결하려면
함수 시작 부분에 위치 중단점을 설정합니다.
마우스 오른쪽 단추로 중단점을 클릭하고 조건을 선택합니다.
중단점 조건 대화 상자에서 조건 확인란을 클릭합니다. 고급 중단점을 참조하세요.
텍스트 상자에
Var==3
같은 식을 입력합니다. 여기서Var
은 잘못된 값을 포함하는 매개 변수의 이름이고3
은 이 매개 변수에 전달된 잘못된 값입니다.참인 경우 라디오 단추를 선택하고 확인 단추를 클릭합니다.
이제 프로그램을 다시 실행합니다.
Var
매개 변수의 값이3
인 경우 중단점은 함수의 시작 부분에서 프로그램을 중단하게 합니다.호출 스택 창을 사용하여 호출하는 함수를 찾고 함수의 소스 코드를 탐색합니다. 자세한 내용은 방법: 호출 스택 창 사용을 참조하세요.
함수를 수백 번 호출하는 경우 어떤 호출이 실패했는지 어떻게 알 수 있나요?
예: 내 프로그램에서 특정 함수 CnvtV
에 대한 호출에 실패합니다. 실패하기 전에 프로그램이 이 함수를 여러 번 호출하는 것 같습니다. CnvtV
에 위치 중단점을 설정하면 해당 함수가 호출될 때마다 프로그램이 중지되기는 하지만 내가 원하는 것이 아닙니다. 어떤 조건 때문에 호출이 실패하는지 알 수 없기 때문에 조건부 중단점을 설정할 수 없습니다. 무엇을 도와드릴까요?
적중 횟수 필드를 도달할 수 없는 높은 값으로 설정하여 함수에 중단점을 설정합니다. 이 경우 CnvtV
함수가 수백 번 호출되었다고 생각되면 적중 횟수를 1000 이상으로 설정할 수 있습니다. 프로그램을 실행한 다음 호출이 실패할 때까지 기다립니다. 호출에 실패하면 중단점 창을 열고 중단점 목록을 확인합니다. CnvtV
에 설정한 중단점 다음에 적중 횟수와 남아 있는 반복 횟수가 표시됩니다.
CnvtV(int) (no condition) when hit count is equal to 1000 (currently 101)
이제 함수가 101번째 호출에서 실패한다는 것을 알 수 있습니다. 중단점에서 적중 횟수를 101로 설정하고 다시 프로그램을 실행하면 실패 원인이 된 CnvtV
함수가 호출될 때 프로그램이 중지됩니다.
Win32 오류 코드를 어디에서 찾을 수 있나요?
기본 시스템 설치의 INCLUDE 디렉터리에 있는 WINERROR.H에는 Win32 API 함수에 대한 오류 코드 정의가 포함되어 있습니다.
조사식 창이나 간략한 조사식 대화 상자에 코드를 입력하면 오류 코드를 찾을 수 있습니다. 예시:
0x80000004,hr
앱에서 단계별로 실행하는 경우 어떻게 포커스를 유지할 수 있습니까?
예: 프로그램에 창 활성화 문제가 생겼습니다. 프로그램에서 단계별로 디버거를 실행하면 프로그램이 계속해서 포커스를 잃어 버리기 때문에 문제 재현 기능이 방해를 받습니다. 포커스를 잃지 않도록 방지할 수 있는 방법이 있나요?
다른 컴퓨터가 있을 경우 원격 디버깅을 사용합니다. 호스트에서 디버거를 실행하는 동안 원격 컴퓨터에서 프로그램을 작동시킬 수 있습니다. 자세한 내용은 방법: 원격 컴퓨터 선택을 참조하세요.
Windows API 함수를 어떻게 디버그할 수 있나요?
NT 기호가 있는 Windows API 함수에 중단점을 설정하려면:
함수 중단점에서 함수가 있는 DLL의 이름과 함께 함수 이름을 입력합니다(컨텍스트 연산자 참조). 32비트 코드에서는 함수 이름의 데코레이팅된 형식을 사용합니다. 예를 들어 MessageBeep에 중단점을 설정하려면 다음을 입력해야 합니다.
{,,USER32.DLL}_MessageBeep@4
데코레이트된 이름을 가져오려면 데코레이트된 이름 보기를 참조하세요.
데코레이트된 이름을 테스트하고 디스어셈블리 코드에서 볼 수 있습니다. Visual Studio 디버거의 함수에서 일시 중지된 동안 코드 편집기 또는 호출 스택 창에서 함수를 마우스 오른쪽 단추로 클릭하고 디스어셈블리로 이동을 선택합니다.
64비트 코드에서 데코레이트되지 않은 이름을 사용할 수 있습니다.
{,,USER32.DLL}MessageBeep