C语言的入口函数
起因
因为调试Rust,在main函数打了断点看了调用堆栈的信息.顺便看看C语言中在调用main函数之前的堆栈信息.这里主要以控制台程序为例.C语言中调用main函数的堆栈信息

先看一下调用的关系图:
在C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.24.28314\crt\src\vcruntime目录中,找到了exe_main.cpp文件,
#define _SCRT_STARTUP_MAIN
#include "exe_common.inl"
extern "C" int mainCRTStartup()
{
return __scrt_common_main();
}
在exe_common.inl文件中,可以看到__scrt_common_main函数. 可以先看看不同程序(控制台/窗口程序),调用的函数是不一样的.
//
// exe_common.inl
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// The implementation of the common executable entry point code. There are four
// executable entry points defined by the CRT, one for each of the user-definable
// entry points:
//
// * mainCRTStartup => main
// * wmainCRTStartup => wmain
// * WinMainCRTStartup => WinMain
// * wWinMainCRTStartup => wWinMain
//
// These functions all behave the same, except for which user-definable main
// function they call and whether they accumulate and pass narrow or wide string
// arguments. This file contains the common code shared by all four of those
// entry points.
//
// The actual entry points are defined in four .cpp files alongside this .inl
// file. At most one of these .cpp files will be linked into the resulting
// executable, so we can treat this .inl file as if its contents are only linked
// into the executable once as well.
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();
}
在vs2019的VCRuntime下,找到源码看到上面的调用关系,基本上看不到堆初始化代码了,在官方文档上看到,在vs2015的时候,重构CRT(C Runtime),不过上面的代码也能了解调用的关系了.
秋风
2020-04-07