爲了調試目的(獲取調用堆棧),我正在努力將地址映射到它們的符號。 MS dbghelp.dll可以從地址中分辨符號(請參閱SymFromAddr
,MSDN)。但是,它不工作,我不知道這到底是怎麼過的工作,因爲地址似乎與程序的每次運行變化:爲什麼函數的地址會隨着每次運行而改變?
#include <iostream>
void Foo() {}
int _tmain(int argc, _TCHAR* argv[])
{
const long unsigned int addr = reinterpret_cast<long unsigned int>(&Foo);
std::cout << "Address: " << std::hex << addr << std::endl;
return 0;
}
輸出:
D:\dev\Sandbox\Debug>Sandbox.exe
Address: 901320
D:\dev\Sandbox\Debug>Sandbox.exe
Address: ce1320
D:\dev\Sandbox\Debug>Sandbox.exe
Address: 3a1320
D:\dev\Sandbox\Debug>Sandbox.exe
Address: 3f1320
怎麼可能不同以往的程序從堆棧跟蹤中讀取地址並將其映射到函數?這聽起來對我來說很神奇。我沒有在鏈接的文檔中找到任何說我必須從地址或其他東西中減去某些東西的東西。
在我的理解中,由於我們克服了實模式,每一個進程都有一個虛擬內存空間,因此不需要再爲一個加載地址擲骰子。如果是DLL,我會理解絕對地址的不確定性,但不是主要的可執行文件。
使用VS2008試用Win7。
這個隨機化的幾個答案,謝謝!我就像跆拳道!如何在這個超級MS「安全通過默默無聞」堆棧轉儲有用嗎? – Borph 2013-04-25 12:35:13
因爲所有調試器都可以處理隨機加載的模塊。 DLL一直在移動。 – MSalters 2013-04-25 12:54:25