2010-03-13 84 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