电子商务网站建设人才,浙江公司响应式网站建设推荐,合肥营销网站建设,aso优化技术最近还遇到一个例子是关于#xff1a;从C转C开发需要注意的一个意识问题。本人遇到的这个问题是#xff0c;带着C的意识来看C的代码#xff0c;然后根据代码看#xff0c;有一个全局变量的值在main函数进入之后才会更改#xff0c;所以百思不得其解#xff0c;这个变量怎…最近还遇到一个例子是关于从C转C开发需要注意的一个意识问题。本人遇到的这个问题是带着C的意识来看C的代码然后根据代码看有一个全局变量的值在main函数进入之后才会更改所以百思不得其解这个变量怎么在main函数之前发生了改变
这里的一个区别是C里全局变量的构造函数是先于main函数执行。当然在C的环境下也可以注册先于main函数执行的代码这个有名的例子就是qemu/vpp的实现里面有很多全局对象最终会标记一个编译属性 attribute((constructor))根据gcc文档里这个属性的作用 The constructor attribute causes the function to be called automatically before execution enters main (). Similarly, the destructor attribute causes the function to be called automatically after main () completes or exit () is called. Functions with these attributes are useful for initializing data that is used implicitly during the execution of the program. 那究竟是怎么实现的呢这个可用通过查看一个qemu的调用栈来看其中的流程
(gdb) bt #0 0x0000555555c5f6b0 in qemu_thread_create () #1 0x0000555555c67f69 in ?? () #2 0x0000555555c9a88d in __libc_csu_init () #3 0x00007ffff4874d18 in __libc_start_main () from /lib64/libc.so.6 #4 0x00005555558a859e in _start ()
binfmt_elf.c /* Get the exec-header */ loc-elf_ex *((struct elfhdr *)bprm-buf);
[rootvmtca-2003 ~]# readelf -e abc.elf ELF Header: Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 Class: ELF64 Data: 2’s complement, little endian Version: 1 (current) OS/ABI: UNIX - System V ABI Version: 0 Version: 0x1 Entry point address: 0x3afe0
nm abc.elf | grep 3afe0
000000003afe0 T _start
这样就能捋顺了是Linux内核的系统调用execve系列在加载二进制文件的时候根据二进制接口读取了文件的exe头部这个头部里含有程序入口点。这个入口点是_start函数。接下来_start会做main函数之前的一些初始化的工作包含全局变量的构造函数的调用。 这就可以根据glibc里的代码查看具体是怎么实现的这个方式。