Любой способ вызвать локальные переменные к стеку в приложении VC на 64 бита

Когда приложение VC 2005 года на 64 бита компилируется с включенной оптимизацией, не возможно видеть все локальные переменные в файле дампа катастрофического отказа. Во многих случаях локальные переменные или параметры хранятся в регистрах вместо на стеке. Последующие вызовы к другим функциям, таким как обработка ошибок функции, будут иногда перезаписывать те значения. Это мешает прослеживать причину проблемы. Существует ли способ вызвать локальные переменные и/или параметры к стеку во время выполнения?

Выключение оптимизации является одним путем, но это подает медленную заявку, и это обычно - не хорошая идея для сборки конечных версий. Я надеюсь, что существует вызов времени выполнения, который выведет все локальные переменные и/или реестр где-нибудь. Если существует такая функция, мы можем затем вызвать функцию прежде, чем вызвать функцию регистрации ошибок и надо надеяться сможем видеть больше локальной переменной на стеке.

- Alex

6
задан skaffman 11 February 2010 в 08:21
поделиться

3 ответа

Если вы возьмете адрес переменной, компилятор будет вынужден выделить для нее место в стеке, чтобы вы могли написать небольшой макрос.

#ifdef DEBUG
 #define FORCE_ON_STACK(var)  void * p##var##_dummy = (void *)&var
#else
 #define FORCE_ON_STACK(var)  (void)0 // eat the ;
#endif

В некоторых случаях компилятор все еще может лениться синхронизировать значение в стеке с регистрами. Кроме того, хранение аргументов в регистрах - важная оптимизация, которую это, по крайней мере частично, победит, поэтому это несколько повлияет на производительность.

1
ответ дан 17 December 2019 в 04:46
поделиться

Есть ли способ принудительно поместить локальные переменные и / или параметры в стек во время выполнения?

Это совершенно непрактично; это потребует повторной компиляции кода. Ответ Джона Кнеллера - ваш лучший выбор, иначе вам нужно прерывать каждую запись функции и записывать состояние регистра.

0
ответ дан 17 December 2019 в 04:46
поделиться

Думаю, вы видите кое-что еще. Наиболее распространенные соглашения о вызовах на x86 передают аргументы аргументам функции в стеке.Но соглашение о вызовах x64 другое, оно похоже на __fastcall на x86, оно передает первые 4 аргумента функции в регистрах (rcx, rdx, r8 и r9). Если функция нетривиальна, компилятор сразу же генерирует код для сохранения этих регистров во фрейме стека.

К сожалению,отладчик недостаточно умен, чтобы знать о сохраненных местоположениях регистров. Он отображает значение регистра в стеке вызовов, значение, которое почти всегда менялось. Вы можете технически самостоятельно извлечь значение аргумента из фрейма стека, но вы действительно очень хотите, чтобы это произошло. В оптимизированном коде это смещение от rsp, а не от rbp, и значение указателя стека также изменилось.

Я пока не нашел подходящего обходного пути. С нетерпением жду улучшений в отладчике VS2010, понятия не имею, было ли это решено.

3
ответ дан 17 December 2019 в 04:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: