AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / unix / Perguntas / 429188
Accepted
Yves
Yves
Asked: 2018-03-10 00:35:23 +0800 CST2018-03-10 00:35:23 +0800 CST 2018-03-10 00:35:23 +0800 CST

A biblioteca de vínculo dinâmico deve ser carregada na RAM

  • 772

Como sabemos, qualquer arquivo executável, que esteja em execução, é carregado na RAM.

Além disso, temos dois tipos de bibliotecas: biblioteca de links estáticos e biblioteca de links dinâmicos.

Os dois tipos de bibliotecas também devem ser carregados na RAM enquanto são necessários.

Como eu sei, temos duas maneiras de carregar a biblioteca dinâmica:

  1. vinculá-lo durante a compilação, comog++ -lsofile
  2. carregar dinamicamente no código, temos dlopenque fazer isso

Postei esta pergunta , mas ainda não posso ter certeza de que poderíamos listar todos os arquivos lib. Para o primeiro caso acima, acho que podemos obter o arquivo de link com ldd, ou verificar /proc/{PID}/maps. Mas para o segundo caso, estou pensando se consigo pegar os arquivos de link com algum método, segue um exemplo:

void SomeModule()
{
    //dlopen here to link mysofile
}

int main()
{
    if (user_enter == 'a')
    {
        printf("hello world");
    }
    else
    {
        SomeModule();
    }
}

Neste exemplo, quando o executarmos e digitarmos always a, o dlopennunca será chamado, portanto mysofilenunca será vinculado, ou seja mysofile, nunca será carregado na RAM. Estou certo?

Em caso afirmativo, como posso obter os arquivos lib necessários do arquivo executável, exceto lendo o código-fonte?

dynamic-linking
  • 2 2 respostas
  • 1524 Views

2 respostas

  • Voted
  1. Basile Starynkevitch
    2018-03-10T02:10:50+08:002018-03-10T02:10:50+08:00

    Como sabemos, qualquer arquivo executável, que esteja em execução, é carregado na RAM.

    Errado !

    um arquivo executável é mapeado no espaço de endereço virtual dos processos que o executam, pelo subsistema de memória virtual do kernel. A RAM física é gerenciada apenas pelo kernel. Leia Sistemas Operacionais: Três Peças Fáceis para saber mais.

    Nem todo o segmento de código desse arquivo executável é paginado (não carregado!) na RAM. Em particular, um grande trecho de código que nunca é usado (por exemplo, porque contém alguma função grande que nunca é chamada) não irá para a RAM. Leia sobre paginação e cache de página .

    Às vezes, não há RAM física suficiente para lidar convenientemente com todas as páginas necessárias. Nessa situação, você observa uma surra .

    o vinculador dinâmico (consulte ld-linux(8) ) e também dlopen(3) usa mmap(2) para mapear a memória de alguns segmentos da biblioteca compartilhada. Portanto, não carrega todo o segmento de código do plug-in na RAM. Leia também o artigo Como escrever bibliotecas compartilhadas de Drepper .

    quando o executamos e digitamos sempre a, o dlopen nunca será chamado, então mysofile nunca será vinculado, o que significa que mysofile nunca será carregado na RAM.

    Em geral, não há absolutamente nenhuma maneira de prever quais futuras bibliotecas compartilhadas seriam usadas e dlopeneditadas. Pense nos dois cenários a seguir:

    • um programa de longa duração (talvez o seu navegador) pede ao usuário para obter alguma biblioteca compartilhada (talvez baixando-a da rede) e depois dlopen.

    • um processo está gerando algum código C em um arquivo temporário /tmp/emittedcode.c, compile (ao forkexecutar um processo apropriado executando alguns gcc -O -Wall -fPIC /tmp/emittedcode.c -shared -o /tmp/emittedcode.so) esse arquivo em um plug-in temporário /tmp/emittedcode.soe dlopen-s esse plug-in temporário (é claro que depois dlsym-ing símbolos apropriados lá).

    Eu gosto bastante da segunda abordagem. Observe que compilar para C é um hábito bem estabelecido. E os compiladores atuais são rápidos o suficiente para permitir fazer isso em alguma interação REPL.

    BTW, em um desktop Linux, um processo pode ter dlopen muitos objetos compartilhados, ou seja, plugins (pelo menos centenas de milhares e provavelmente milhões). Veja meu manydl.cexemplo (que gera código C "aleatório" em arquivos temporários e repita).

    PS. Esteja ciente também do Halting Problem , relacionado à impossibilidade teórica de prever todos os dlopencaminhos futuros.

    • 3
  2. Best Answer
    Stephen Kitt
    2018-03-10T00:52:10+08:002018-03-10T00:52:10+08:00

    Você está certo, se dlopennunca for chamado, a biblioteca de destino nunca será carregada na memória (do processo).

    Determinar as bibliotecas necessárias sem ler o código-fonte parece uma variante do problema da parada. Você pode usar algumas heurísticas: se o programa não estiver vinculado a libdl, ele não poderá usar dlopen; em caso afirmativo, você pode usar strace(consulte Como descobrir as cargas executáveis ​​das bibliotecas dinâmicas quando executadas? ) Ou tentar descobrir os argumentos para dlopenusar a análise estática. Mas o programa pode incluir libdldiretamente (por meio de links estáticos ou construindo o código); e como o vinculador dinâmico não é mágico, não há nada que impeça um programa de reimplementá-lo sozinho, então você não pode ser absolutamentecertifique-se de ter capturado todas as bibliotecas necessárias usando essas heurísticas. Talvez existam programas que descobrem que estão sendo rastreados e pulam o carregamento da biblioteca ...

    A única maneira segura de listar todas as bibliotecas necessárias é ler o código-fonte.

    • 1

relate perguntas

  • O arquivo ld.so.cache não é um arquivo binário

  • A que se refere o interpretador relatado por `file`?

  • Gerenciamento de versão secundária da biblioteca compartilhada

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Como exportar uma chave privada GPG e uma chave pública para um arquivo

    • 4 respostas
  • Marko Smith

    ssh Não é possível negociar: "nenhuma cifra correspondente encontrada", está rejeitando o cbc

    • 4 respostas
  • Marko Smith

    Como podemos executar um comando armazenado em uma variável?

    • 5 respostas
  • Marko Smith

    Como configurar o systemd-resolved e o systemd-networkd para usar o servidor DNS local para resolver domínios locais e o servidor DNS remoto para domínios remotos?

    • 3 respostas
  • Marko Smith

    Como descarregar o módulo do kernel 'nvidia-drm'?

    • 13 respostas
  • Marko Smith

    apt-get update error no Kali Linux após a atualização do dist [duplicado]

    • 2 respostas
  • Marko Smith

    Como ver as últimas linhas x do log de serviço systemctl

    • 5 respostas
  • Marko Smith

    Nano - pule para o final do arquivo

    • 8 respostas
  • Marko Smith

    erro grub: você precisa carregar o kernel primeiro

    • 4 respostas
  • Marko Smith

    Como baixar o pacote não instalá-lo com o comando apt-get?

    • 7 respostas
  • Martin Hope
    rocky Como exportar uma chave privada GPG e uma chave pública para um arquivo 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Wong Jia Hau ssh-add retorna com: "Erro ao conectar ao agente: nenhum arquivo ou diretório" 2018-08-24 23:28:13 +0800 CST
  • Martin Hope
    Evan Carroll status systemctl mostra: "Estado: degradado" 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim Como podemos executar um comando armazenado em uma variável? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S Por que /dev/null é um arquivo? Por que sua função não é implementada como um programa simples? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 Como ver as últimas linhas x do log de serviço systemctl 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - pule para o final do arquivo 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla Por que verdadeiro e falso são tão grandes? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis Substitua a string em um arquivo de texto enorme (70 GB), uma linha 2017-12-30 06:58:33 +0800 CST
  • Martin Hope
    Bagas Sanjaya Por que o Linux usa LF como caractere de nova linha? 2017-12-20 05:48:21 +0800 CST

Hot tag

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve