[英]Need help understanding stack frame layout
在為調試器實現堆棧遍歷器時,我正在努力將參數提取到函數調用並顯示它們。 為簡單起見,我從純32位(調試器和debuggee)開始使用cdecl約定,該函數帶有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 Update 3中進行任何優化。
我已經通過使用dia2dump
示例應用程序在pdb中查找來驗證是否確實將其編譯為cdecl。 我不明白是什么導致堆棧看起來像這樣,它與我學到的內容都不匹配,也與Microsoft提供的文檔不匹配。
我還對Google進行了大量檢查(包括osdev Wiki頁面,msdn博客文章等),並檢查了我的(到現在可能已經過時的)有關32位x86匯編編程的書(這些書在64位CPU存在之前就已發布) 。
非常感謝您的任何解釋或鏈接!
正如Raymond所指出的那樣,與棧框架的基礎相比,我以某種方式誤解了函數調用的參數最終出現在內存中的情況。 這是固定的代碼段:
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); /* <-- Read before the stack frame */
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 */
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.