我们从比特币的客户端启动顺序作为入口来分析代码,先看下面这个函数:AppInitBasicSetup,初始化应用基础设置
bool AppInitBasicSetup(const ArgsManager& args, std::atomic<int>& exit_status)
{
// ********************************************************* Step 1: setup
#ifdef _MSC_VER
// Turn off Microsoft heap dump noise
_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
_CrtSetReportFile(_CRT_WARN, CreateFileA("NUL", GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, 0, 0));
// Disable confusing "helpful" text message on abort, Ctrl-C
_set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
#endif
#ifdef WIN32
// Enable heap terminate-on-corruption
HeapSetInformation(nullptr, HeapEnableTerminationOnCorruption, nullptr, 0);
#endif
if (!SetupNetworking()) {
return InitError(Untranslated("Initializing networking failed."));
}
#ifndef WIN32
// Clean shutdown on SIGTERM
registerSignalHandler(SIGTERM, HandleSIGTERM);
registerSignalHandler(SIGINT, HandleSIGTERM);
// Reopen debug.log on SIGHUP
registerSignalHandler(SIGHUP, HandleSIGHUP);
// Ignore SIGPIPE, otherwise it will bring the daemon down if the client closes unexpectedly
signal(SIGPIPE, SIG_IGN);
#else
SetConsoleCtrlHandler(consoleCtrlHandler, true);
#endif
std::set_new_handler(new_handler_terminate);
return true;
}
现在我们来详细解释每一步:
#ifdef _MSC_VER 和 #ifdef WIN32 是条件编译指令,用于在不同平台或使用不同编译器时进行条件编译。在这里,它们分别用于 Microsoft 编译器和 Windows 操作系统。
_CrtSetReportMode 和 _CrtSetReportFile 是用于设置 Microsoft 编译器的内存报告模式和文件的函数。在这里,将内存报告模式设置为文件模式,防止输出到控制台。同时,通过设置 _set_abort_behavior 来禁用在中止(abort)、Ctrl-C时显示令人困惑的“有帮助”的文本消息。
HeapSetInformation 用于启用堆的终止处理,当检测到堆损坏时,应用程序会终止。
SetupNetworking 函数用于初始化网络设置。如果网络初始化失败,返回初始化错误。
在非 Windows 平台上,通过 registerSignalHandler 注册信号处理器。对 SIGTERM 和 SIGINT 信号执行 HandleSIGTERM 函数,对 SIGHUP 信号执行 HandleSIGHUP 函数。此外,通过 signal(SIGPIPE, SIG_IGN) 忽略 SIGPIPE 信号,以防止客户端非正常关闭导致守护进程崩溃。
SetConsoleCtrlHandler 用于注册控制台控制处理程序 consoleCtrlHandler。
std::set_new_handler(new_handler_terminate) 设置新的 new 操作符错误处理程序为 new_handler_terminate 函数。
返回 true,表示初始化成功。
这段代码执行了一系列系统和库的初始化工作,确保比特币程序在运行时能够正常工作,并在发生错误时返回适当的错误信息。