CDB (Microsoft Console Debugger) 및 WinDbg을 사용하여 힙 손상이 발생했을 때 ReadFile에 P/Invoke을 강제로 중단하려고 시도했습니다. 나는 chBuf 배열에 할당 한 것보다 더 많은 바이트를 텍스트 파일에서 읽습니다. 디버거에서 GC.Collect
이후에 액세스 위반이 표시되지 않습니다. 이 너무 늦습니다.입니다. 내 프로그램을 실행하기 전에 나는 실행한다가비지 수집하기 전에 힙 손상을 검색하십시오.
gflags -p /enable testheap.exe /unaligned
효과는 쓸데없는 것처럼 보인다. 나는이 작은 테스트 프로그램을 작성하여 힙 손상 문제가있는 훨씬 더 큰 상용 프로그램을 디버깅하는 데 적용했습니다.
Application Verifier 및 MDA callbackOnCollectedDelegate를 사용하여 DebugDiag를 성공적으로 사용해 보았습니다. 내 gflags
의 사용은 ReadFile 직후 힙 손상을 감지하지 않습니까?
코드 : chBuf
이후
byte[] chBuf = new byte[8];
는 CLR에 의해 관리되지 GFLAGS :
namespace TestHeap
public partial class Form1 : Form
{
[DllImport("kernel32.dll", SetLastError = true)]
static extern SafeFileHandle CreateFile(string lpFileName, uint dwDesiredAccess,
uint dwShareMode, IntPtr lpSecurityAttributes, uint dwCreationDisposition,
uint dwFlagsAndAttributes, IntPtr hTemplateFile);
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool ReadFile(SafeFileHandle hFile, [Out] byte[] lpBuffer,
uint nNumberOfBytesToRead, out uint lpNumberOfBytesRead, IntPtr lpOverlapped);
string fileName = "testHeap.txt";
const uint GENERIC_READ = 0x80000000;
const uint OPEN_EXISTING = 3;
SafeFileHandle sh;
byte[] chBuf = new byte[8];
public Form1()
{
InitializeComponent();
}
private void testBtn_Click(object sender, EventArgs e)
{
bool nStat;
uint bytesToRead = 1025;
uint bytesRead = 0;
if (!(nStat = ReadFile(sh, chBuf, bytesToRead, out bytesRead, IntPtr.Zero)))
Debug.Print("testBtn_Click error in ReadFile, nStat = {0}", nStat);
MessageBox.Show(string.Format("After ReadFile, bytesToRead = {0},\n bytes read = {1}", bytesToRead, bytesRead));
GC.Collect();
MessageBox.Show("testBtn_Click end, after GC.Collect");
}
private void Form1_Load(object sender, EventArgs e)
{
sh = CreateFile(fileName, GENERIC_READ, 0, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
}
}
}
확실하지 않음 그것은 액세스 위반이 발생하는 지점입니다. 디버거에서 액세스 위반 *이 발생하기 전에 어떻게 볼 수 있습니까? 'GC.Collect'까지 손상이 발견되지 않았다는 것을 의미한다면,'HeapValidate'를 명시 적으로 호출하는 것처럼 손상을 더 빨리 찾아야합니다. –
Raymond, GC.Collect보다 먼저 액세스 위반이 발생합니다. GC를 깨고! GC 전에 확인하면 관리 힙이 이미 손상되었음을 알 수 있습니다. gflags를 설정하면이를 잡아야합니다. Microsoft 지원 문서 ID : 286470을 참조하십시오. 광고 된대로 작동하지 않습니다. 내 상용 프로그램에서 GC가 힙 손상 후 오래 발생할 수 있습니다. 힙이 손상된 시점에 예외가 발생해서는 안됩니까? 디버거가 왜 그것을 잡을 수 없습니까? –
또한 Win32 HeapValidate는 관리되는 힙 문제를 검사하는 데 유용하지 않습니다. 그것을 사용하기위한 올바른 주장을 어떻게 제시 할 것입니까? –