Como as chamadas do sistema do man 2 são chamadas?

1

Por chamadas do sistema, quero dizer funções como man 2 brk , não a 0x80 interrupção.

Se eu entendi este tópico corretamente, um programa C compilado nunca DIRETAMENTE invoca chamadas do sistema. Ele só pode chamar chamadas de biblioteca, que podem ser vinculadas dinamicamente a partir de glibc .

No entanto, man 3 brk retorna No manual entry for brk in section 3 . Então eu acho que uma das seguintes coisas tem que acontecer para o brk ser executado corretamente:

  1. Meu entendimento acima está errado. Os programas podem invocar chamadas do sistema sem glibc support. Mas como é que brk está ligado ao programa?
  2. Existe, de fato, um wrapper glibc para a chamada do sistema brk . Então qual brk é incluído quando eu #include <unistd.h> ? O glibc um ou o sistema chamam um? Se for o glibc , por que não está documentado em man 3 ? Onde posso encontrar uma lista completa de chamadas de biblioteca disponíveis?
por wlnirvana 15.06.2017 / 12:02

2 respostas

3

Para a maioria das chamadas do sistema com páginas man na seção 2, as páginas man realmente descrevem os wrappers da biblioteca C. As exceções são geralmente mencionadas explicitamente, como gettid que @Sergei Kurenkov se refere em sua resposta:

NOTES Glibc does not provide a wrapper for this system call; call it using syscall(2).

Da mesma forma, com pivot_root (que não é útil para aplicativos gerais), tgkill (que executa a função de baixo nível de pthread_kill ). Depois, há readdir , em que a chamada real do sistema é um pouco diferente da função de biblioteca :

DESCRIPTION This is not the function you are interested in. Look at readdir(3) for the POSIX conforming C library interface. This page documents the bare kernel system call interface, which is superseded by getdents(2).

Note que tem que haver algum tipo de wrapper. Chamadas de função são feitas usando as convenções de chamada C, que é diferente da convenção de chamada da interface do kernel. Chamadas de função usuais são feitas com a instrução call assembly (ou similar), chamadas de kernel com syscall ou int 0x80 (e isso não está contando coisas como gettimeofday ou getpid no vdso ). O compilador não (precisa) saber quais chamadas de função mapeiam para uma chamada de kernel real.

Mesmo com as chamadas de sistema "usuais", o wrapper da biblioteca C atua de forma ligeiramente diferente da chamada do sistema: as chamadas do sistema retornam os códigos de erro como valores negativos variáveis (se você observar o código do kernel, verá muitos retornos como return -EPERM; ). O wrapper da biblioteca C transforma todos esses valores de retorno em -1 e move o código de erro real para errno .

    
por 15.06.2017 / 13:23
2

a compiled C program never DIRECTLY invokes system calls.

não é verdade. Pegue um gettid como um exemplo: link . Ele não tem um wrapper então você precisa escrever no seu programa algo como (do man: Glibc does not provide a wrapper for this system call; call it using syscall(2). ):

#ifndef WIN32

#include <linux/unistd.h>
#include <sys/syscall.h>
#include <unistd.h>
int thread_gettid(void) {
    return static_cast<int>(syscall(SYS_gettid));
}
#else
int thread_gettid(void) {
    return GetCurrentThreadId();
}
#endif

My understanding above is wrong. Programs can invoke system calls without glibc support.

De fato, pode. Ele usa o link syscall : .

But how is brk linked into the program then?

Parece que brk tem realmente um wrapper na glibc, já que existe essa linha no homem:

The return value described above for brk() is the behavior provided 
by the glibc wrapper function for the Linux brk() system call.

If it is the glibc one, why is it not documented in man 3

Acho que é porque há malloc para alocações de memória que precisam ser usadas:

Avoid using brk() and sbrk(): the malloc(3) memory allocation package is the portable and comfortable way of allocating memory.

    
por 15.06.2017 / 12:25