在VS2017中创建一个控制台C++应用程序:
#include "pch.h"
#include <iostream>
int func()
{
return 1;
}
int v = func();
int main()
{
}
在main()函数中设置一个断点,开始调试,然后调用堆栈看起来像:
testCppConsole.exe!main() Line 8 C++
testCppConsole.exe!invoke_main() Line 78 C++
testCppConsole.exe!__scrt_common_main_seh() Line 288 C++
testCppConsole.exe!__scrt_common_main() Line 331 C++
testCppConsole.exe!mainCRTStartup() Line 17 C++
kernel32.dll!@BaseThreadInitThunk@12() Unknown
ntdll.dll!__RtlUserThreadStart() Unknown
ntdll.dll!__RtlUserThreadStart@8() Unknown
程序的入口点是mainCRTStartup,它最终调用C语言的入口点main(),并且变量v的值将会是1。
现在将链接器(Linker)的高级选项(Advanced)中的入口点(Entry Point)设置为"main",并开始进行调试,此时调用堆栈(Call Stack)如下:
> testCppConsole.exe!main() Line 8 C++
kernel32.dll!@BaseThreadInitThunk@12() Unknown
ntdll.dll!__RtlUserThreadStart() Unknown
ntdll.dll!__RtlUserThreadStart@8() Unknown
所以main()成为程序入口点,这一次v的值将为0,因为没有调用CRT init函数,因此func()也不会被调用。
现在修改代码如下:
#include "pch.h"
#include <iostream>
extern "C" int mainCRTStartup();
extern "C" int entry()
{
return mainCRTStartup();
}
int func()
{
return 1;
}
int v = func();
int main()
{
}
并设置链接器>高级>入口点为“entry”,然后开始调试,现在的调用堆栈是:
> testCppConsole.exe!main() Line 14 C++
testCppConsole.exe!invoke_main() Line 78 C++
testCppConsole.exe!__scrt_common_main_seh() Line 288 C++
testCppConsole.exe!__scrt_common_main() Line 331 C++
testCppConsole.exe!mainCRTStartup() Line 17 C++
testCppConsole.exe!entry() Line 10 C++
kernel32.dll!@BaseThreadInitThunk@12() Unknown
ntdll.dll!__RtlUserThreadStart() Unknown
ntdll.dll!__RtlUserThreadStart@8() Unknown
然后v将再次变为1。程序入口点是entry(),它调用mainCRTStartup(),该函数调用CRT初始化函数,该函数调用func()来初始化v,最终mainCRTStartup()调用main()。
mainCRTStartup
基本上看起来像这样:init_tls(); init_crt(); run_global_constructors(); get_args(&argc, &argv); ret = main(argc, argv); run_global_destructors(); exit(ret);
。因此,main
函数在其中某个位置。 - Damon