Порядок 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

Трудно сказать точно, почему переупорядочение распределений решило бы проблему, но если вы скопировали инструкции в их буфер, а затем проделали большую работу, прежде чем прыгнуть в буфер, это, вероятно, улучшило бы шансы на то, чтобы "сойти с рук". поскольку кэши ЦП будут иметь больше возможностей для очистки другими способами.

Другие вопросы по тегам