【问题标题】:Does every call to write sends switches to kernel mode?是否每次调用 write 都会切换到内核模式?
【发布时间】:2018-07-15 08:40:18
【问题描述】:


我知道调用 glibc“write”函数会调用 sys_call write 函数,它是一个内核函数。
因为 sys_call 是一个内核函数,所以 CPU 必须将环更改为零存储进程寄存器和等等。
但它总是切换到内核模式吗?例如,如果我这样做

write(-1,buffer,LENGTH)

它是否仍然试图在文件描述符数组中找到它?
我在 glibc 源代码中看到它确实检查 fd>0,但我没有看到任何跳转到 sys_call 那里(似乎 main() 的 baracks 在对 alias_write 的任何调用之前结束。

/* Write NBYTES of BUF to FD.  Return the number written, or -1.  */
ssize_t
__libc_write (int fd, const void *buf, size_t nbytes)
{
  if (nbytes == 0)
    return 0;
  if (fd < 0)
    {
      __set_errno (EBADF);
      return -1;
    }
  if (buf == NULL)
    {
      __set_errno (EINVAL);
      return -1;
    }

  __set_errno (ENOSYS);
  return -1;
}
libc_hidden_def (__libc_write)
stub_warning (write)

weak_alias (__libc_write, __write)
libc_hidden_weak (__write)
weak_alias (__libc_write, write)
#include <stub-tag.h>

所以问题是:

  1. glibc 在哪里实际调用了 sys_write
  2. 如果 fd

【问题讨论】:

    标签: linux linux-kernel glibc


    【解决方案1】:

    我在 glibc 源代码中看到它确实检查 fd>0,但我没有看到任何跳转到 sys_call 那里

    您正在查看错误的代码。

    __libc_write 在不同的条件下使用有多种定义。你看的是io/write.c

    实际上在 Linux 上使用的那个是从 sysdeps/unix/syscall-template.S 生成的,它确实实际上执行切换到内核模式(并返回到用户模式),即使在fd==-1

    【讨论】:

      猜你喜欢
      • 2012-06-20
      • 2016-12-26
      • 1970-01-01
      • 1970-01-01
      • 2013-10-04
      • 2015-04-07
      • 1970-01-01
      • 2010-10-23
      • 1970-01-01
      相关资源
      最近更新 更多