Я использую CDB (отладчик консоли Microsoft) и WinDbg, чтобы попытаться заставить перерыв, когда разложение кучи происходит на P/Invoke в ReadFile. Я прочитал еще много байтов из текстового файла, чем то, что я выделил для массива chBuf. Отладчик не видит нарушения доступа до GC.Collect
, что составляет слишком поздно для меня. Перед запуском моей программы я запускаюОбнаружить кучу коррупции ПЕРЕД сборкой мусора
gflags -p /enable testheap.exe /unaligned
Эффект кажется бесполезным. Я написал эту небольшую тестовую программу, чтобы применить то, что я нахожу, для отладки гораздо более крупной коммерческой программы, которая имеет проблемы с кучей коррупции.
Я также пробовал DebugDiag с Application Verifier и MDA callbackOnCollectedDelegate без успеха. Разве мое использование gflags
не должно быть обнаружено сразу после ReadFile?
Код:
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'.» В этом и заключается нарушение прав доступа. Как отладчик может видеть нарушение прав доступа до того, как оно произойдет?? Если вы имеете в виду, что коррупция не обнаружена до «GC.Collect», вам просто нужно искать коррупцию раньше, например, путем явного вызова «HeapValidate». –
Raymond, нарушение доступа происходит до GC.Collect. Если я разорву и проведу проверку до GC, это показывает, что управляемая куча уже повреждена. Установка gflags должна поймать это. См. Поддержку Microsoft для Microsoft ID статьи: 286470. Это просто не работает для меня, как рекламируется. В моей коммерческой программе GC может произойти уже после кучи. Не следует ли исключать исключение в момент повреждения кучи? Почему тогда отладчик не поймал его? –
Кроме того, Win32 HeapValidate не кажется полезным для проверки проблем с управляемой кучей. Как бы вы указали правильные аргументы в пользу использования этого? –