При внедрении хоста стека для отладчика, над которым я работаю, я достиг точки, чтобы извлечь аргументы для вызова функции и отобразить их. Чтобы упростить это, я начал с соглашения cdecl в чистом 32-битном (как отладчике, так и в debuggee) и функции, которая принимает 3 параметра. Тем не менее, я не могу понять, почему аргументы в трассировке стека не соответствуют по сравнению с тем, что определяет cdecl (справа налево, ничего в регистрах), несмотря на то, что он пытается понять это в течение нескольких дней.Нужна помощь в понимании структуры фрейма стека
Вот представление вызова функции Я пытаюсь трассировки стека:
void Function(unsigned long long a, const void * b, unsigned int c) {
printf("a=0x%llX, b=%p, c=0x%X\n", a, b, c);
_asm { int 3 }; /* Because I don't have stepping or dynamic breakpoints implemented yet */
}
int main(int argc, char* argv[]) {
Function(2, (void*)0x7A3FE8, 0x2004);
return 0;
}
Это то, что функция (неудивительно) выводится на консоль:
a=0x2, c=0x7a3fe8, c=0x2004
Это (отладчик ловит точку останова и там я пытаюсь пройти стек):
0x3EF5E0: 0x10004286 /* previous pc */
0x3EF5DC: 0x3EF60C /* previous fp */
0x3EF5D8: 0x7A3FE8 /* arg b --> Wait... why is b _above_ c here? */
0x3EF5D4: 0x2004 /* arg c */
0x3EF5D0: 0x0 /* arg a, upper 32 bit */
0x3EF5CC: 0x2 /* arg a, lower 32 bit */
Код, который отвечает за демпинг фреймов стека (реализуется с помощью DIA SDK, хотя, я не думаю, что имеет отношение к моей проблеме) выглядит следующим образом:
ULONGLONG stackframe_top = 0;
m_frame->get_base(&stackframe_top); /* IDiaStackFrame */
/* dump 30 * 4 bytes */
for (DWORD i = 0; i < 30; i++)
{
ULONGLONG address = stackframe_top - (i * 4);
DWORD value;
SIZE_T read_bytes;
if (ReadProcessMemory(m_process, reinterpret_cast<LPVOID>(address), &value, sizeof(value), &read_bytes) == TRUE)
{
debugprintf(L"0x%llX: 0x%X\n", address, value); /* wrapper around OutputDebugString */
}
}
Я компиляции тестовая программа без какой-либо оптимизации в обновлении vs2015 3.
Я подтвердил, что я действительно скомпилировал ее как cdecl, посмотрев в pdb с образцом приложения dia2dump
. Я не понимаю, что заставляет стек выглядеть так, это не соответствует чему-либо, что я узнал, и не соответствует documentation provided by Microsoft.
Я также проверил google много (включая страницы wiki wsdev, сообщения в блоге msdn и т. Д.) И проверил мои (к настоящему времени устаревшие) книги по 32-битовому программированию на сборке x86 (которые были выпущены до 64-разрядных процессоров существовало).
Благодарим вас за любые объяснения или ссылки!
Это, вероятно, поможет, если вы явно задали вопрос, вместо того, чтобы просто объяснить, что вы не понимаете. Вы можете улучшить свой вопрос, добавив информацию о том, что вы ожидали от стека. – IInspectable
Извинения, я думал, что это подразумевалось мной, заявляя, что я работаю с соглашениями о вызовах cdecl, вот что я получаю за предположения. Я уточню вопрос. – Warepire
Ум, вы смотрите на местных жителей, а не на параметры. Это, вероятно, оставшиеся параметры printf. –