2010-03-13 114 views
1

我有一個在ARMV4I處理器上運行的Winodws Mobile 6.1應用程序。給定一個堆棧地址(從解除異常),我喜歡確定哪個模塊擁有該地址。按堆棧地址查找模塊

使用ToolHelpAPI,我能夠確定使用下面的方法最模塊:

HANDLE snapshot = ::CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_GETALLMODS, 0); 
if(INVALID_HANDLE_VALUE != snapshot) 
{ 
    MODULEENTRY32 mod = { 0 }; 
    mod.dwSize = sizeof(mod); 
    if(::Module32First(snapshot, &mod)) 
    { 
     do { 
      if(stack_address > (DWORD)mod.modBaseAddr && 
       stack_address < (DWORD)(mod.modBaseAddr + mod.modBaseSize)) 
      { 
       // Found the module! 
       // offset = stack_address - mod.modBaseAddr 
       break; 
      } 
     } while(::Module32Next(snapshot, &mod)); 
    } 
    ::CloseToolhelp32Snapshot(snapshot); 
} 

// if it's still not found 

snapshot = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS | TH32CS_SNAPNOHEAPS, 0); 
if(INVALID_HANDLE_VALUE != snapshot) 
{ 
    PROCESSENTRY32 proc = { 0 }; 
    proc.dwSize = sizeof(proc); 
    if(::Process32First(snapshot, &proc)) 
    { 
     do 
     { 
      if(stack_address > proc.th32MemoryBase && 
       stack_address < (proc.th32MemoryBase + 0x2000000)) 
      { 
       // Found the executable 
       // offset = stack_address - proc.th32MemoryBase 
       break; 
      } 

     } while(::Process32Next(snapshot, &proc)); 
    } 
    ::CloseToolhelp32Snapshot(snapshot); 
} 

但是,我並不總是似乎能找到的地址相匹配的模塊。例如:

stack address  module  offset 
0x03f65bd8  coredll.dll + 0x0001bbd8 
0x785cab1c  mylib.dll + 0x0002ab1c 
0x785ca9e8  mylib.dll + 0x0002a9e8 
0x785ca0a0  mylib.dll + 0x0002a0a0 
0x785c8144  mylib.dll + 0x00028144 
0x3001d95c   my.exe + 0x0001d95c 
0x3001dd44   my.exe + 0x0001dd44 
0x3001db90   my.exe + 0x0001db90 
0x03f88030  coredll.dll + 0x0003e030 
0x03f8e46c  coredll.dll + 0x0004446c 
0x801087c4    ???  
0x801367b4    ???  
0x8010ce78    ???  
0x801086dc    ???  
0x03f8e588  coredll.dll + 0x00044588 
0x785a56a4  mylib.dll + 0x000056a4 
0x785bdd60  mylib.dll + 0x0001dd60 
0x785bbd0c  mylib.dll + 0x0001bd0c 
0x785bdb38  mylib.dll + 0x0001db38 
0x3001db20   my.exe + 0x0001db20 
0x3001dc40   my.exe + 0x0001dc40 
0x3001a8a4   my.exe + 0x0001a8a4 
0x3001a79c   my.exe + 0x0001a79c 
0x03f67348  coredll.dll + 0x0001d348 

我在哪裏可以找到那些丟失的堆棧地址?有什麼建議麼?

感謝, PaulH

編輯:通過採取@肥皂盒的建議,我已經填補了一些空白與「my.exe」

+1

該函數是否返回您期望的所有模塊?也許它失去了一些重要的東西(比如你的主程序,或者kernel32,或者其他東西)......你的地址比較不應該是<=/> =而不是? – SoapBox 2010-03-13 00:51:12

+0

@SoapBox - 有趣。不,它沒有。 1項缺失。我的應用程序是一個由.exe加載的DLL。該.exe從列表中丟失。 – PaulH 2010-03-13 00:57:58

+0

從超過1個庫丟失的地址看,這可能不是你的答案,但也許它解釋了一些缺失的東西。 – SoapBox 2010-03-13 00:59:45

回答

0

的CPU堆棧包含的不僅僅是代碼的地址了。函數參數也在堆棧上傳遞。只有調試器才能確切知道堆棧幀中的內容,它從.pdb文件中獲取它。這不會對你有所幫助,程序不能自行調試。在常規的Windows上,你可以使用一個小型轉儲來進行事後分析,但不知道它是否可以在移動設備上使用。它應該是。

+0

你是說那些0x80000000地址不參考代碼?他們可以提及什麼樣的事情? – PaulH 2010-03-13 07:27:21

+0

@PaulH:數據,正如我所解釋的。可能是浮動參數。 – 2010-03-13 13:06:23