Я использую CDB (Microsoft Console Debugger) и WinDbg, чтобы попытаться принудительно прервать работу при повреждении кучи. происходит с помощью P/Invoke в ReadFile. Я прочитал из текстового файла гораздо больше байтов, чем я выделил массиву chBuf. Отладчик не видит нарушения прав доступа до тех пор, пока не произойдет GC.Collect
, что для меня слишком поздно. Перед запуском моей программы я запускаю
gflags -p /enable testheap.exe /unaligned
Эффект кажется бесполезным. Я написал эту маленькую тестовую программу, чтобы применить то, что я нашел, для отладки гораздо более крупной коммерческой программы, которая имеет проблемы с повреждением кучи.
Я также попробовал DebugDiag с Application Verifier и обратный вызов MDAOnCollectedDelegate безуспешно. Разве мое использование 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
. - person Raymond Chen   schedule 31.10.2011HeapValidate
проверяет только кучи, созданные с помощьюHeapCreate
. Неуправляемая куча не была создана таким образом, поэтому вам придется найти соответствующую функцию проверки для неуправляемой стороны. (Из описания проблемы не было ясно, было ли повреждение в управляемой или неуправляемой куче, хотя я должен был подумать об этом немного больше.) Я не знаю, есть ли соответствующий, пожалуйста, отсканируйте управляемую кучу для коррупционная функция. - person Raymond Chen   schedule 31.10.2011HeapCreate
. Они ничего не знают о пользовательских кучах, таких как неуправляемая куча. - person Raymond Chen   schedule 31.10.2011