.NET / Rotor源码分析5 - 开始使用WinDbg+SOS调试,sscoree.dll,加载SOS并设置JIT断点
2007-12-14 18:56
901 查看
准备工作
在经过一番准备之后,现在我们可以开始正式使用WinDbg+SOS来调试托管代码了。如果你没有看过前两篇文章,那么请先阅读这两篇文章以对WinDbg+SOS有一个大致的了解。这两篇文章的链接在这里:.NET Rotor源码研究4 – 修改Rotor使其发送CLR Notification:http://blog.csdn.net/ATField/archive/2007/05/21/1618535.aspx.NET Rotor源码研究3 - 调试Rotor托管代码的利器:WinDbg和SOS:http://blog.csdn.net/ATField/archive/2007/05/12/1606151.aspx除此之外,还需要准备一个小程序来进行调试,本文所使用的程序如下:(hello.cs) namespace Hello { class Hello { public static void Main(string[] args) { System.Console.WriteLine("Your name please?"); string s = System.Console.ReadLine(); Welcome(s); Welcome(s); } public static void Welcome(string name) { System.Console.WriteLine("Hello " + name); } } } |
env dbg |
cd binaries.x86dbg.rotor csc hello.cs |
windbg clix hello.exe |
程序的加载
启动调试器,我们停在程序加载的位置,Call Stack如下(如果你没有Windows系统DLL所对应的Symbol,那么你看到的会有所不同,这里因为有Symbol,结果更加准确):ntdll!DbgBreakPoint ntdll!LdrpDoDebuggerBreak+0x31 ntdll!LdrpInitializeProcess+0xffc ntdll!_LdrpInitialize+0xf5 ntdll!LdrInitializeThunk+0x10 |
bp clix!PAL_startup_main g |
int __cdecl main(int argc, char **argv) { // 省略… nExitCode = Launch(pModuleName, pActualCmdLine); } DWORD Launch(WCHAR* pFileName, WCHAR* pCmdLine) { // 省略… nExitCode = _CorExeMain2(NULL, 0, pFileName, NULL, pCmdLine); return nExitCode; } |
SSCOREE_SHIM_RET ( __int32, STDMANGLE(_CorExeMain2,20), ( PBYTE pUnmappedPE, DWORD cUnmappedPE, LPWSTR pImageNameIn, LPWSTR pLoadersFileName, LPWSTR pCmdLine), ( pUnmappedPE, cUnmappedPE, pImageNameIn, pLoadersFileName, pCmdLine), -1) |
SSCOREE_LIB_START (mscorwks) SSCOREE_SHIM_RET ( HRESULT, STDMANGLE(MetaDataGetDispenser,12),SSCOREE_LIB_END (mscorwks) … … SSCOREE_LIB_END (mscorwks) SSCOREE_LIB_START (mscorpe) … SSCOREE_LIB_END (mscorpe) SSCOREE_LIB_START (mscordbi) … … |
#define SSCOREE_SHIM_BODY(FUNC,RET_COMMAND,SIG_RET,SIG_ARGS,ARGS) / do { / SSCOREE_SHIM_CUSTOM_INIT / FARPROC proc_addr = SscoreeShimGetProcAddress ( / SHIMSYM_ ## FUNC, / #FUNC); / _ASSERTE (proc_addr); / if (proc_addr) { / RET_COMMAND ((SIG_RET (STDMETHODCALLTYPE *)SIG_ARGS)proc_addr)ARGS; / } / } while (0) #define SSCOREE_SHIM_RET(SIG_RET,FUNC,SIG_ARGS,ARGS,ONERROR) / extern "C" / SIG_RET STDMETHODCALLTYPE FUNC SIG_ARGS / { / SSCOREE_SHIM_BODY (FUNC, return, SIG_RET, SIG_ARGS, ARGS); / return ONERROR; / } #define SSCOREE_SHIM_NORET(FUNC,SIG_ARGS,ARGS) / extern "C" / void STDMETHODCALLTYPE FUNC SIG_ARGS / { / SSCOREE_SHIM_BODY (FUNC, ; ,void, SIG_ARGS, ARGS); / } |
FARPROC SscoreeShimGetProcAddress ( ShimmedSym SymIndex, LPCSTR SymName) { FARPROC proc; #ifdef TRACE_LOADS printf ("SscoreeShimGetProcAddress: Loading Symbol %d (%s)/n", SymIndex, g_Syms[SymIndex].Name); #endif _ASSERTE (SYM_INDEX_VALID (SymIndex)); _ASSERTE (SymName); _ASSERTE (g_Syms[SymIndex].Name); _ASSERTE (!strcmp (g_Syms[SymIndex].Name, SymName)); proc = g_Syms[SymIndex].Proc; if (proc == NULL) { proc = SetupProc(SymIndex, SymName); } return proc; } |
static FARPROC SetupProc ( ShimmedSym SymIndex, LPCSTR SymName) { HMODULE lib_handle; FARPROC proc; ShimmedLib LibIndex = FindSymbolsLib (SymIndex); _ASSERTE (LIB_INDEX_VALID (LibIndex)); #ifdef TRACE_LOADS printf ("SscoreeShimGetProcAddress: Loading library %d (%S)/n", LibIndex, g_Libs[LibIndex].Name); #endif lib_handle = g_Libs[LibIndex].Handle; if (lib_handle == NULL) { lib_handle = SetupLib (LibIndex); if (lib_handle == NULL) return NULL; } _ASSERTE (lib_handle); proc = g_Syms[SymIndex].Proc; if (proc == NULL) { proc = GetProcAddress (lib_handle, SymName); if (!proc) { #ifdef _DEBUG fprintf (stderr, "SscoreeShimGetProcAddress: GetProcAddress (/"%s/") failed/n", SymName); #endif return proc; } g_Syms[SymIndex].Proc = proc; } return proc; } |
ShimmedLib FindSymbolsLib ( ShimmedSym SymIndex) { // some trickery to figure out which library this symbol is in _ASSERTE (SYM_INDEX_VALID (SymIndex)); #define SSCOREE_LIB_START(LIBNAME) / if (SymIndex < SHIMLIB_ ## LIBNAME) { / return LIB_ ## LIBNAME; / } / if (SymIndex == SHIMLIB_ ## LIBNAME) { / return LIB_ ## MAX_LIB; / } #include "sscoree_shims.h" return LIB_MAX_LIB; } |
HMODULE SetupLib ( ShimmedLib LibIndex) { HMODULE lib_handle; WCHAR FullPath[_MAX_PATH]; if (!PAL_GetPALDirectory (FullPath, _MAX_PATH)) { return NULL; } if (wcslen(FullPath) + wcslen(g_Libs[LibIndex].Name) >= _MAX_PATH) { SetLastError(ERROR_FILENAME_EXCED_RANGE); return NULL; } wcsncat(FullPath, g_Libs[LibIndex].Name, _MAX_PATH); lib_handle = LoadLibrary (FullPath); if (lib_handle == NULL) { #ifdef _DEBUG fprintf (stderr, "SscoreeShimGetProcAddress: LoadLibrary (/"%S/") failed/n", FullPath); DisplayMessageFromSystem(GetLastError()); #endif return lib_handle; } g_Libs[LibIndex].Handle = lib_handle; #ifdef _DEBUG // first time we've hit this library. Run some tests. SscoreeVerifyLibrary (LibIndex); #endif ROTOR_PAL_CTOR_TEST_RUN(SSCOREE_INT); return lib_handle; } |
dv FullPath |
FullPath = wchar_t [260] "D:/usr/src/sscli20/binaries.x86dbg.rotor/mscorwks.dll" |
g mscorwks!_CorExeMain2 |
//***************************************************************************** // This entry point is called from the native entry piont of the loaded // executable image. The command line arguments and other entry point data // will be gathered here. The entry point for the user image will be found // and handled accordingly. //***************************************************************************** __int32 STDMETHODCALLTYPE _CorExeMain2( // Executable exit code. PBYTE pUnmappedPE, // -> memory mapped code DWORD cUnmappedPE, // Size of memory mapped code __in LPWSTR pImageNameIn, // -> Executable Name __in LPWSTR pLoadersFileName, // -> Loaders Name __in LPWSTR pCmdLine) // -> Command Line { |
加载SOS,设置断点
对了,现在我们还需要加载SOS,因为SOS需要mscorwks,因此在这个时候加载SOS正合适。在调试器中输入: .loadby sos mscorwks |
!bpmd hello.exe Hello.Hello.Main g |
(11fc.1088): CLR notification exception - code e0444143 (first chance) CLR notification: module 'sorttbls.nlp' loaded (11fc.1088): CLR notification exception - code e0444143 (first chance) (11fc.1088): CLR notification exception - code e0444143 (first chance) CLR notification: method 'Hello.Hello.Main(System.String[])' code generated (11fc.1088): CLR notification exception - code e0444143 (first chance) JITTED hello!Hello.Hello.Main(System.String[]) |
Blog: http://blog.csdn.net/atfield
转载请注明出处
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1618557
相关文章推荐
- .NET / Rotor源码分析5 - 开始使用WinDbg+SOS调试,sscoree.dll,加载SOS并设置JIT断点
- .NET / Rotor源码分析5 - 开始使用WinDbg+SOS调试,sscoree.dll,加载SOS并设置JIT断点
- .NET / Rotor源码分析5 - 开始使用WinDbg+SOS调试,sscoree.dll,加载SOS并设置JIT断点
- .NET / Rotor源码分析5 - 开始使用WinDbg+SOS调试,sscoree.dll,加载SOS并设置JIT断点
- .NET / Rotor源码分析5 - 开始使用WinDbg+SOS调试,sscoree.dll,加载SOS并设置JIT断点
- .NET / Rotor源码分析5 - 开始使用WinDbg+SOS调试,sscoree.dll,加载SOS并设置JIT断点
- .NET / Rotor源码分析5 - 开始使用WinDbg+SOS调试,sscoree.dll,加载SOS并设置JIT断点
- .NET / Rotor源码分析5 - 开始使用WinDbg+SOS调试,sscoree.dll,加载SOS并设置JIT断点
- .NET / Rotor源码分析5 - 开始使用WinDbg+SOS调试,sscoree.dll,加载SOS并设置JIT断点
- .NET / Rotor源码分析5 - 开始使用WinDbg+SOS调试,sscoree.dll,加载SOS并设置JIT断点
- .NET / Rotor源码分析5 - 开始使用WinDbg+SOS调试,sscoree.dll,加载SOS并设置JIT断点
- .NET / Rotor源码分析5 - 开始使用WinDbg+SOS调试,sscoree.dll,加载SOS并设置JIT断点
- .NET / Rotor源码分析5 - 开始使用WinDbg+SOS调试,sscoree.dll,加载SOS并设置JIT断点
- .NET / Rotor源码分析5 - 开始使用WinDbg+SOS调试,sscoree.dll,加载SOS并设置JIT断点
- .NET / Rotor源码分析5 - 开始使用WinDbg+SOS调试,sscoree.dll,加载SOS并设置JIT断点
- .NET / Rotor源码分析5 - 开始使用WinDbg+SOS调试,sscoree.dll,加载SOS并设置JIT断点
- .NET / Rotor源码分析5 - 开始使用WinDbg+SOS调试,sscoree.dll,加载SOS并设置JIT断点
- .NET / Rotor源码分析5 - 开始使用WinDbg+SOS调试,sscoree.dll,加载SOS并设置JIT断点
- .NET / Rotor源码分析5 - 开始使用WinDbg+SOS调试,sscoree.dll,加载SOS并设置JIT断点
- .NET / Rotor源码分析5 - 开始使用WinDbg+SOS调试,sscoree.dll,加载SOS并设置JIT断点