Syscall implementation of exit()

柔情痞子 提交于 2019-11-26 17:14:51

问题


I wrote a simple C program which just calls the exit() function, however strace says that the binary is actually calling exit_group, is exit() a exit_group() wrapper? Are these two functions equivalent? If so why would the compiler choose exit_group() over exit()?


回答1:


The Linux and glibc man pages document all of this (See especially the "C library/kernel differences" in the NOTES section).

  • _exit(2): In glibc 2.3 and later, this wrapper function actually calls the Linux sys_exit_group system call to exit all threads. Before glibc2.3, it was a wrapper for sys_exit to exit just the current thread.
  • sys_exit: terminates just the current thread, leaving others running. AFAIK, modern glibc has no wrapper function for this Linux system call, because it's usually not useful.
  • exit_group(2): glibc wrapper for sys_exit_group, which exits all threads.
  • exit(3): The ISO C89 function which flushes buffers and then exits the whole process. (It always uses exit_group() because there's no benefit to checking if the process was single-threaded and deciding to use sys_exit vs. sys_exit_group). As @Matteo points out, recent ISO C or POSIX standards are thread-aware and one or both probably require this behaviour.

    But apparently exit(3) itself is not thread-safe (in the C library cleanup parts), so I guess don't call it from multiple threads at once.

Only exit(), not _exit() or exit_group(), flushes stdout, leading to "printf doesn't print anything" problems in newbie asm programs if writing to a pipe (which makes stdout full-buffered instead of line-buffered), or if you forgot the \n in the format string. For example, How come _exit(0) (exiting by syscall) prevents me from receiving any stdout content?. If you use any buffered I/O functions, or at_exit, or anything like that, it's usually a good idea to call the libc exit(3) function instead of the system call directly. But of course you can call fflush before sys_exit_group.


It's not of course the compiler that chose anything, it's libc. When you include headers and write read(fd, buf, 123) or exit(1), the C compiler just sees an ordinary function call.

Some C libraries (e.g. musl, but not glibc) may use inline asm to inline a syscall instruction into your binary, but still the headers are part of the C library, not the compiler.



来源:https://stackoverflow.com/questions/46903180/syscall-implementation-of-exit

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!