Порядок VirtualAlloc, кажется, имеет значение (C++)
У меня странное поведение при использовании virtualalloc. Я в C++, Visual Studio 2010.
У меня есть две вещи, которые я хочу выделить, и я использую VirtualAlloc (у меня есть свои причины, не относящиеся к вопросу)
1 - место для хранения буфера кода сборки x86
2 - Пространство для хранения структуры данных, которую хочет код x86
В моем коде я делаю:
thread_data_t * p_data = (thread_data_t*)VirtualAlloc(NULL, sizeof(thread_data_t), MEM_COMMIT, PAGE_READWRITE);
//set up all the values in the structure
unsigned char* p_function = (unsigned char*)VirtualAlloc(NULL, sizeof(buffer), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
memcpy(p_function, buffer, sizeof(buffer));
CreateThread( 0, (LPTHREAD_START_ROUTINE)p_function, p_data, 0, NULL);
в режиме отладки: работает нормально
в режиме RELEASE: ускоренный поток получает нулевое значение в качестве входных данных. Проверено через отладку, что при вызове createThread указатель верный
если я переключаю VirtualAlloc так, чтобы я выделил пространство функций перед пространством данных, то оба режима DEBUG и RELEASE работают нормально.
Есть идеи почему? Я проверил все мои настройки сборки VS одинаковы между DEBUG/RELEASE
1 ответ
После копирования кода сборки в буфер памяти вы не можете просто перейти прямо в этот буфер. Вам нужно очистить кэш процессора и т.п., иначе он не будет работать. Ты можешь использовать FlushInstructionCache
сделать это.
https://msdn.microsoft.com/en-us/library/windows/desktop/ms679350%28v=vs.85%29.aspx
Трудно сказать точно, почему переупорядочение распределений решило бы проблему, но если вы скопировали инструкции в их буфер, а затем проделали большую работу, прежде чем прыгнуть в буфер, это, вероятно, улучшило бы шансы на то, чтобы "сойти с рук". поскольку кэши ЦП будут иметь больше возможностей для очистки другими способами.