Linux/Windows中atexit实现机制


想起atexit的实现是怎么个原理。

于是就写了简单的函数来调查。

#include  <stdio.h>

#include <string.h>

#include <stdlib.h>

 

void show1(void)

{

printf("This is in show1\n");

return;

}

void show2(void)

{

printf("This is in show2\n");

return;

}

int main()

{

atexit(show1);

atexit(show2);

printf("This is in main\n");

return 0;

}

在Windows中,用的是vs2005调试。阅读汇编代码,发现

在Windows中,是把每一次注册的函数放在一个地址,然后每当再注册一个一个函数时,则把该地址加4。

这样当函数执行完main函数返回时,先于基地址比较,如果不相等,然后再取出该地址中的函数地址,比较是否为0,

如果为NULL,则继续,如果不为NULL,则执行该地址的函数。

 

在Linux中(UBT中9.**),采取了不同的机制。

在Linux中,存放了一个计数器。先判断是否为该计数器是否为0。

如果为0,则表示没有注册函数。

如果大于0,则说明有注册函数。

另外在Linux中,注册函数是存放在一个大小为16字节的结构体中,每个结构体有一个成员是注册函数地址。

struct atexit_fn {

int fn_type; /* ATEXIT_? from above */

union {

    void (*std_func)(void);void (*cxa_func)(void *);

    #ifdef __BLOCKS__void (^block)(void);

    #endif /* __BLOCKS__ */

    }fn_ptr; /* function pointer */

    void *fn_arg; /* argument for CXA callback */

    void *fn_dso; /* shared module handle */

}

详细参考http://www.opensource.apple.com/source/Libc/Libc-763.11/stdlib/atexit-fbsd.c

另外今天顺便测试了一下,在Windows中,前65k字节是不能读写的。

相关内容