免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 7487 | 回复: 12
打印 上一主题 下一主题

[C] atexit()问题~ [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-07-05 23:11 |只看该作者 |倒序浏览
哪位大侠帮忙解释下 atexit()函数是在main()结束前执行呢还是在结束之后执行呢???

论坛徽章:
0
2 [报告]
发表于 2010-07-05 23:54 |只看该作者
man 3 exit

论坛徽章:
0
3 [报告]
发表于 2010-07-06 00:05 |只看该作者
本帖最后由 没本 于 2010-07-06 00:36 编辑

如果你又问:那么exit()是在main()之后执行的么?
我只能建议你做如下实验:

  1. $ echo "int main(){return 0;}" > test.c
  2. $ gcc -g -o test test.c
  3. $ gdb test
  4. GNU gdb (GDB) 7.1
  5. Copyright (C) 2010 Free Software Foundation, Inc.
  6. License GPLv3+: GNU GPL version 3 or later <[url]http://gnu.org/licenses/gpl.html[/url]>
  7. This is free software: you are free to change and redistribute it.
  8. There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
  9. and "show warranty" for details.
  10. This GDB was configured as "i686-pc-linux-gnu".
  11. For bug reporting instructions, please see:
  12. <[url]http://www.gnu.org/software/gdb/bugs/[/url]>...
  13. Reading symbols from /home/foo/tmp/test...done.
  14. (gdb) b exit
  15. Function "exit" not defined.
  16. Make breakpoint pending on future shared library load? (y or [n]) y

  17. Breakpoint 1 (exit) pending.
  18. (gdb) b main
  19. Breakpoint 2 at 0x8048377: file test.c, line 1.
  20. (gdb) r
  21. Starting program: /home/foo/tmp/test

  22. Breakpoint 2, main () at test.c:1
  23. 1       int main(){return 0;}
  24. (gdb) n
  25. 0xb7e95c76 in __libc_start_main () from /lib/libc.so.6
  26. (gdb) c
  27. Continuing.

  28. Breakpoint 1, 0xb7eace14 in exit () from /lib/libc.so.6
  29. (gdb) c
  30. Continuing.

  31. Program exited normally.
  32. (gdb)
复制代码
相信科学,远离邪+教。

论坛徽章:
0
4 [报告]
发表于 2010-07-06 00:07 |只看该作者
另一佐证:
__libc_start_main

Name

__libc_start_main -- initialization routine
Synopsis

int __libc_start_main(int *(main) (int, char * *, char * *), int argc, char * * ubp_av, void (*init) (void), void (*fini) (void), void (*rtld_fini) (void), void (* stack_end));

Description

The __libc_start_main() function shall perform any necessary initialization of the execution environment, call the main function with appropriate arguments, and handle the return from main(). If the main() function returns, the return value shall be passed to the exit() function.

Note: While this specification is intended to be implementation independent, process and library initialization may include:

performing any necessary security checks if the effective user ID is not the same as the real user ID.

initialize the threading subsystem.

registering the rtld_fini to release resources when this dynamic shared object exits (or is unloaded).

registering the fini handler to run at program exit.

calling the initializer function (*init)().

calling main() with appropriate arguments.

calling exit() with the return value from main().

This list is an example only.
__libc_start_main() is not in the source standard; it is only in the binary standard.

See Also

The section on Process Initialization in each of the architecture specific supplements.

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
5 [报告]
发表于 2010-07-06 00:10 |只看该作者
理论上说:

1. 标准要求main返回等效于调用exit
c99 5.1.2.2.3 Program termination

2. exit首先会调用atexit注册的函数
c99 7.20.4.3 The exit function


从实践出发:

1. 可以写个程序大致猜测

  1. #include <stdlib.h>
  2. int main() {
  3.       struct local {
  4.             ~local() { printf("before return\n"); }
  5.       static void onexit() { printf("in atexit\n"); }
  6.       } l;
  7.       atexit(&local::onexit);
  8.       return 0;
  9. }
复制代码
2. 查看进程启动代码

进程、线程的启动代码都是如下形式:

  1. exit( main( argc, argv ) );
  2. _endthreadex( thread_routine(arg) );
复制代码
这是如何保证main返回等效于调用exit的方法。
这里可以看出, exit是在main返回之后, 以main的返回值来调用。
从这里也可以看出, 最好是让main或者线程函数返回到它们的caller, 然后由caller余下部分的代码调用exit或者_endthreadex。

如果直接调用exit或_endthreadex, 从调用点到这个启动main或线程的caller之间的frame的清理工作就不会被执行。

论坛徽章:
2
程序设计版块每日发帖之星
日期:2015-06-17 22:20:00每日论坛发贴之星
日期:2015-06-17 22:20:00
6 [报告]
发表于 2010-07-06 06:12 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
7 [报告]
发表于 2010-07-06 07:24 |只看该作者
回复 6# pmerofc

这不矛盾。

"main返回等效于以main的返回值调用exit"是有前提的。
违反这个前提条件, 结束状态就是unspecified。

而void main显然违反这个前提条件……

c99 5.1.2.2.3 Program termination
——依然是这里

If the return type of the main function is a type compatible with int, a return from the
initial call to the main function is equivalent to calling the exit function with the value
returned by the main function as its argument;10)

——前提在黑体中

reaching the } that terminates the main function returns a value of 0.

——这是C99新加的, 和C++兼容。

If the return type is not compatible with int,
the termination status returned to the host environment is unspecified.

——void main属于这一类。

论坛徽章:
0
8 [报告]
发表于 2010-07-06 10:48 |只看该作者
回复 3# 没本


    谢谢了~~~~~呵呵,明白啦~~~

论坛徽章:
0
9 [报告]
发表于 2010-07-06 11:02 |只看该作者
回复 5# OwnWaterloo


    谢谢阿~~~~明白啦~~呵呵

论坛徽章:
2
程序设计版块每日发帖之星
日期:2015-06-17 22:20:00每日论坛发贴之星
日期:2015-06-17 22:20:00
10 [报告]
发表于 2010-07-06 17:39 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP