Rust的入口函数
起因
在调试Rust的时候,在Clion调用堆栈信息看到的.程序最早执行的不是main函数.在Windows下mainCRTStartup(其实在执行mainCRTStartup先执行其他的,只是看不到调用的函数,只能看到调用了ntdll.dll和kernel32.dll).先看看图.

在上图看到main函数,不是Rust的main函数,在main函数调用lang_start函数,可以说这个是Rust程序中的入口函数.
看一下调用关系图:
看过调用关系图,在看代码就容易理解了.lang_start函数,在Windows下C:/Users/用户名/.rustup/toolchains/stable-x86_64-pc-windows-gnu/lib/rustlib/src/rust/src/libstd/rt.rs
代码
fn lang_start_internal(
main: &(dyn Fn() -> i32 + Sync + crate::panic::RefUnwindSafe),
argc: isize,
argv: *const *const u8,
) -> isize {
use crate::panic;
use crate::sys;
use crate::sys_common;
use crate::sys_common::thread_info;
use crate::thread::Thread;
sys::init();
unsafe {
let main_guard = sys::thread::guard::init();
sys::stack_overflow::init();
// Next, set up the current Thread with the guard information we just
// created. Note that this isn't necessary in general for new threads,
// but we just do this to name the main thread and to give it correct
// info about the stack bounds.
let thread = Thread::new(Some("main".to_owned()));
thread_info::set(main_guard, thread);
// Store our args if necessary in a squirreled away location
sys::args::init(argc, argv);
// Let's run some code!
let exit_code = panic::catch_unwind(|| {
sys_common::backtrace::__rust_begin_short_backtrace(move || main())
});
sys_common::cleanup();
exit_code.unwrap_or(101) as isize
}
}
#[cfg(not(test))]
#[lang = "start"]
fn lang_start<T: crate::process::Termination + 'static>(
main: fn() -> T,
argc: isize,
argv: *const *const u8,
) -> isize {
lang_start_internal(&move || main().report(), argc, argv)
}
Rust在Windows系统上,目前还是依赖C Runime(msvcrt.dll),可以通过查看生成的exe在petool中看到依赖,所以暂时不清楚是否在lang_start_internal是否堆的初始化,不过可以根据看到代码发现是lang_start_internal实例一个线程并设置为主线程.
秋风
2020-04-07