Windows 平台高级调试与优化 —— VC 开发工具 张银奎 (Raymond Zhang)
为了更好的处理内存问题,我们要尽力保证 Debug 版本(更多的运行检查)和 x64 版本(页堆才能顺利开启)都能顺利编译出来,另外编译器也要及时升级。
版本 发布时间 新增主要功能
Parallel Stack(并行调用栈)
extern "C" int WINAPI
_tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
_In_ LPTSTR lpCmdLine, int nCmdShow)
#pragma warning(suppress: 4985)
{
// call shared/exported WinMain
return AfxWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
}
static int __cdecl invoke_main()
{
return wWinMain(
reinterpret_cast<HINSTANCE>(&__ImageBase),
nullptr,
_get_wide_winmain_command_line(),
__scrt_get_show_window_mode());
}
static __declspec(noinline) int __cdecl __scrt_common_main_seh()
{
if (!__scrt_initialize_crt(__scrt_module_type::exe))
__scrt_fastfail(FAST_FAIL_FATAL_APP_EXIT);
bool has_cctor = false;
__try
{
bool const is_nested = __scrt_acquire_startup_lock();
if (__scrt_current_native_startup_state == __scrt_native_startup_state::initializing)
{
__scrt_fastfail(FAST_FAIL_FATAL_APP_EXIT);
}
else if (__scrt_current_native_startup_state == __scrt_native_startup_state::uninitialized)
{
__scrt_current_native_startup_state = __scrt_native_startup_state::initializing;
if (_initterm_e(__xi_a, __xi_z) != 0)
return 255;
_initterm(__xc_a, __xc_z);
__scrt_current_native_startup_state = __scrt_native_startup_state::initialized;
}
else
{
has_cctor = true;
}
__scrt_release_startup_lock(is_nested);
// If this module has any dynamically initialized __declspec(thread)
// variables, then we invoke their initialization for the primary thread
// used to start the process:
_tls_callback_type const* const tls_init_callback = __scrt_get_dyn_tls_init_callback();
if (*tls_init_callback != nullptr && __scrt_is_nonwritable_in_current_image(tls_init_callback))
{
(*tls_init_callback)(nullptr, DLL_THREAD_ATTACH, nullptr);
}
// If this module has any thread-local destructors, register the
// callback function with the Unified CRT to run on exit.
_tls_callback_type const * const tls_dtor_callback = __scrt_get_dyn_tls_dtor_callback();
if (*tls_dtor_callback != nullptr && __scrt_is_nonwritable_in_current_image(tls_dtor_callback))
{
_register_thread_local_exe_atexit_callback(*tls_dtor_callback);
}
//
// Initialization is complete; invoke main...
//
int const main_result = invoke_main();
//
// main has returned; exit somehow...
//
if (!__scrt_is_managed_app())
exit(main_result);
if (!has_cctor)
_cexit();
// Finally, we terminate the CRT:
__scrt_uninitialize_crt(true, false);
return main_result;
}
__except (_seh_filter_exe(GetExceptionCode(), GetExceptionInformation()))
{
// Note: We should never reach this except clause.
int const main_result = GetExceptionCode();
if (!__scrt_is_managed_app())
_exit(main_result);
if (!has_cctor)
_c_exit();
return main_result;
}
}
// This is the common main implementation to which all of the CRT main functions
// delegate (for executables; DLLs are handled separately).
static __forceinline int __cdecl __scrt_common_main()
{
// The /GS security cookie must be initialized before any exception handling
// targeting the current image is registered. No function using exception
// handling can be called in the current image until after this call:
__security_init_cookie();
return __scrt_common_main_seh();
}
extern "C" int wWinMainCRTStartup()
{
return __scrt_common_main();
}
.expr
if (FirstChance) {
if (PsGetCurrentProcess()->DebugPort == 0 // 没有用户调试器
|| KdIsThisAKdTrap(Tf, &Context)) { // 内核调试器
// 分发给内核调试器
if (KiDebugRoutine &&
KiDebugRoutine(Tf, Reserved, Er, &Context,
PreviousMode, FirstChance) != 0) break;
}
if (DbgkForwardException(TrapFrame,
DebugEvent, FirstChance) != 0) return;
if (valid_user_mode_stack_with_enough_space) {
copy_context_and_exception_record_2_user_stack; // 上下文拷贝到用户空间
TrapFrame->Eip = KeUserExceptionDispatcher; // 飞程序指针
return;
}
}
if (DbgkForwardException(Tf, TRUE, LastChance) != 0) return;
if (DbgkForwardException(Tf, FALSE, LastChance) != 0) return;
ZwTerminateProcess(NtCurrentThread(), Er->ExceptionCode);
windbg -I
D:\dbglabs\bin\release>"D:\Windows Kits\10\Debuggers\x86\gflags.exe" -i heapmfc.exe +ust
Current Registry Settings for heapmfc.exe executable are: 00001000
ust - Create user mode stack trace database
D:\dbglabs\bin\release>"D:\Windows Kits\10\Debuggers\x86\umdh.exe" -pn:heapmfc.exe
from D Profile 是一个 win32/64 CPU,memory 性能分析工具:https://github.com/xwlan/dprofiler D Profiler a lightweight, low overhead CPU Memory IO and Lock profiler for Windows x86/x64. Build in cmd.exe, run command as: msbuild dprofiler.sln
from 最近公司刚买了一台 CEDT 硬件仿真器, 能调试从系统复位到关机重启的所有过程。我拿来跟了一下 windows 的内核启动过程,看了看完全真实的 Windows 初始化过程 :