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 / 708783
Accepted
somega
somega
Asked: 2022-07-07 01:30:39 +0800 CST2022-07-07 01:30:39 +0800 CST 2022-07-07 01:30:39 +0800 CST

Ferramenta para detectar erros na lógica de execução do aplicativo

  • 772

Quero detectar erros na lógica de execução do aplicativo. Por exemplo:

  • esqueci de ligar free()no endereço retornado pormalloc()
  • não fechou o identificador de arquivo retornado poropen()
  • sinalizadores inválidos passados ​​paraopen()
  • identificador de arquivo inválido passado parapoll()
  • write()chamado em fd que não foi aberto para escrita
  • passar sinalizadores inválidos para, open()por exemplo, open("/etc/fstab", 4)
  • chamando close()um fd inválido
  • ...

Acho que tem centenas mais.

Talvez a ferramenta possa ser executada de forma semelhante a ftraceou strace, mas um log do kernel contendo as chamadas defeituosas também seria suficiente.

debugging programming
  • 3 3 respostas
  • 796 Views

3 respostas

  • Voted
  1. Best Answer
    Marcus Müller
    2022-07-07T02:38:33+08:002022-07-07T02:38:33+08:00

    esqueci de ligar free()no endereço retornado pormalloc()

    Bem, malloce freenão são chamadas de kernel! O malloc()que (que é uma função de biblioteca libc, código de processo de usuário normal!)

    1. procure no pool de memória, ele mantém se há um pedaço disponível do tamanho solicitado
    2. em caso afirmativo, marque-o como usado e devolva-o ao programa, caso contrário, chame sbrk(ou equivalentemente, mallocação de memória anônima era comum) para solicitar ao kernel uma quantidade de novas páginas de memória virtual, adicione-as ao pool e, em seguida, satisfazer o pedido do programa.

    freeapenas leva s pedaço de memória retornado anteriormente malloc; em caso afirmativo, ele o marca como não utilizado no pool de memória. (Se não, um comportamento indefinido acontece, mas a maioria das libc's abortará nesse ponto.) A maioria das implementações de freenem mesmo tenta retornar a memória para o sistema operacional!

    Agora, se você quiser limpeza de memória, existem ferramentas (valgrind gcc -fsanitizee mais) que observam essas freee mallocchamadas, e até mesmo rastreiam se o endereço de um mallocpedaço de memória ed ainda está "salvo" em algum lugar do programa, ou se, por exemplo, no final de uma função, o ponteiro que contém esse endereço simplesmente deixa de existir, de modo que ninguém pode lembrar que a memória foi alocada. Isso seria uma falha real; apenas não liberar memória imediatamente ou adiar a liberação para o final do programa não é um problema. Todo o ponto demallocé que você obtém memória com um tempo de vida potencialmente infinito! (dica: se você se preocupa com esse tipo de coisa, e você está certo, não escreva C. Escreva em uma linguagem que permita que os tempos de vida dos objetos sejam rastreados corretamente. Isso seria linguagens como Rust ou C++ , mas o último apenas se não for ensinado por alguém que pensa em C++ como uma extensão para C . Tenho grandes programas onde nunca usei newou pior, mallocem meu código C++. Ponteiros inteligentes podem levar muitas armadilhas de seus ombros, mesmo em C++, que permite que você faça o controle manual da memória, mas nas variantes modernas também o incentiva a não oferecer rastreamento de vida útil de objeto de custo zero. )

    não fechou o identificador de arquivo retornado poropen()

    Isso não é um problema! Ainda mais do que com memória, é perfeitamente aceitável e até sensato manter os arquivos abertos até o final de um programa; por exemplo, bloqueios em arquivos não funcionariam se você os abandonasse imediatamente. E uma interface de controle precisaria ser mantida aberta até que o programa fosse encerrado.

    Novamente, se você está preocupado que dentro do fluxo de controle do seu programa, você pode estar abrindo milhares de arquivos e esquecendo de fechá-los, não escreva em C, mas em uma linguagem onde um identificador de arquivo tem um tempo de vida e pode fechar o descritor de arquivo subjacente quando não for mais necessário.

    Apenas: "há um arquivo aberto, ele ainda não foi fechado" simplesmente não é um problema, especialmente em sistemas POSIX, onde o acesso simultâneo a arquivos é normal e em muitos aspectos até bem definido.

    sinalizadores inválidos passados ​​paraopen()

    Como você sabe disso, além de coisas que retornam um código de erro de qualquer maneira?

    Quero dizer, é muito normal para uma biblioteca verificar se um arquivo pode ser aberto no modo "gravar + anexar", mas não é um problema se não puder ser.

    Se você quiser observar a qualquer momento que uma chamada do sistema é feita, obter seus argumentos e o que ele "retorna" para a terra do usuário, o ptracesyscall é seu amigo, como por exemplo, usado pelo straceprograma popular. Outras opções envolvem a gravação de testes ou uprobes eBPF, que podem ser usados ​​para um registro muito eficiente e até mesmo de "filtragem inteligente" de tais coisas.

    identificador de arquivo inválido passado parapoll()

    Mesmo problema de antes, isso pode ser apenas o seu programa verificando se um identificador de arquivo pode ser pesquisado; esse não é o caso de todos os sistemas de arquivos (pseudo).

    Além disso, pollna verdade também é o nome de uma função wrapper (símbolo) fornecida pelo menos pela glibc, se necessário, e "invalid" para isso pode ser diferente de "invalid" para o pollsyscall.

    • 9
  2. Stephen Kitt
    2022-07-07T01:40:52+08:002022-07-07T01:40:52+08:00

    A primeira delas, não liberar um bloco de memória alocado por malloc(), não envolve necessariamente o kernel — as alocações de memória são tratadas pela biblioteca C. O Memcheck de Valgrind pode detectá-los.

    Para rastrear erros retornados pelo kernel, você pode executar seu programa com strace -Z(disponível desde strace5.2): isso rastreará apenas chamadas de sistema que retornam um erro. Você ainda precisará pós-processar o resultado para procurar, por exemplo EBADFD, EINVALetc.

    Observe que não chamar free()ou close()não é necessariamente um erro; esses recursos são liberados quando o programa é encerrado de qualquer maneira, portanto, há casos em que é perfeitamente aceitável não liberar recursos explicitamente.

    • 4
  3. egherrmann
    2022-07-08T08:35:39+08:002022-07-08T08:35:39+08:00

    Existem várias ferramentas de análise de código estático disponíveis para encontrar erros de codificação comuns como este. Não posso dizer se abrange todos os seus cenários, mas o SonarQube é uma dessas ferramentas com suporte para a linguagem C: https://www.sonarqube.org/features/multi-languages/c

    Existem centenas de regras do SonarQube para C: https://rules.sonarsource.com/c

    SonarQube - C - A memória alocada dinamicamente deve ser liberada

    Se a análise de código estático não for suficiente, você pode precisar de análise dinâmica para examinar o programa em execução: https://en.wikipedia.org/wiki/Dynamic_program_analysis

    • 0

relate perguntas

  • Definindo um estado de cartões SD com falha pelo rastreamento do kernel?

  • Como executo o arquivo .c na linha de comando [duplicado]

  • Como posso fazer meu servidor Linux dormir e acordar na LAN quando não estiver em uso?

  • O que é `bash -x`

  • Como melhorar a capacidade de depuração do Linux e ser proficiente no uso do Linux [fechado]

Sidebar

Stats

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

    Possível firmware ausente /lib/firmware/i915/* para o módulo i915

    • 3 respostas
  • Marko Smith

    Falha ao buscar o repositório de backports jessie

    • 4 respostas
  • Marko Smith

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

    • 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

    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
    user12345 Falha ao buscar o repositório de backports jessie 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl Por que a maioria dos exemplos do systemd contém WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • 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
    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

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