O que é Stack Smashing? Pode ser consertado?

Conteúdo

bola quebrando pilha de moedas

Cada minuto de paralisação da produção geralmente custará dinheiro à empresa. Se o seu aplicativo tiver um obstáculo sério fazendo com que a bateria quebre, está viajando. Aprenda com antecedência o que é destruição de bateria e o que pode ser feito a respeito!!

O que é Stack Smashing?

Trabalhando como engenheiro de garantia de qualidade, mais cedo ou mais tarde encontraremos o termo empilhamento. Como desenvolvedor, este termo provavelmente será descoberto ainda mais cedo, especialmente se um erro foi inserido no código, o que causa uma bateria quebrada. É relativamente facil (como em 'algo fácil’) para um desenvolvedor cometer um erro que introduza quebra da bateria. Como um usuário, quando eu aprender a quebrar baterias, o dano provavelmente já está feito.

A quebra da bateria pode ocorrer involuntariamente, como um exemplo, quando o desenvolvedor introduziu um bug que fez com que a pilha travasse, ou maliciosamente, um invasor que de alguma forma tenta estourar ou corromper a pilha de um programa.

Empilhamento é uma definição com uma definição um tanto vaga que pode apontar para vários problemas e pode vir de uma variedade de fontes. Os dois problemas mais importantes que podem causar o rompimento da bateria são; 1) escrever / superalocação de muitos dados em uma determinada parte da pilha, substituindo assim outra parte da pilha, e 2) onde alguma fonte externa (malicioso ou não) sobrescreveu a pilha de outro programa, mesmo que isso seja muito menos comum .

Então, O que é uma pilha? Esta também é uma definição vagamente definida. Em termos gerais, uma pilha refere-se a uma pilha de processamento de programa, uma pilha de funções definidas em um programa / dado código de software.

Comece imaginando uma pilha de azulejos de banheiro empilhados, pronto para ser usado por um ladrilhador. Esta é uma representação muito boa de uma pilha de computadores., com algumas modificações. Se cada mosaico fosse um pouco deslocado do anterior, seria uma imagem melhor, e logo veremos porque.

Imagine que cada ladrilho empilhado é uma função no programa de computador. A função mais básica está na parte inferior e pode ser, como um exemplo, a main() função em um programa C ou C ++. C y C ++ são duas linguagens de programação que usam a pilha extensivamente.

Cada uma dessas funções no programa C / C ++ terá um nome e provavelmente um conjunto de variáveis ​​de entrada e saída. Em termos simplificados, imagine se uma dessas variáveis ​​tivesse um comprimento de 10 caracteres e alguma outra função digitada acidentalmente 100 caracteres nessa variável. Isso pode danificar toda a pilha..

Em termos do exemplo de bloco acima, imagine alguém com um martelo batendo no primeiro ladrilho com muita força e, assim, quebrando todos os outros ladrilhos. ai está; quebra de pilha 😉

A analogia funciona porque, assim como todos os ladrilhos estão quebrados em nossa imagem de memória fictícia, uma bateria quebrada resultará em 'Funções quebradas’ Se você fingir. Cada deslocamento de bloco é uma função aninhada mais profundamente; mais sobre funções quebradas na próxima seção.

Depuração Bateria (s) estilhaçado

Considerando que, tecnicamente, uma referência a 'Funções quebradas’ pode não estar totalmente correto, Em outras palavras, provavelmente há apenas uma função quebrada, e até mesmo pode não haver uma função interrompida quando há um ataque externo ou um programa com defeito, é uma ótima maneira de pensar sobre uma bateria quebrada.

De repente, nomes de variáveis ​​e funções podem ser alterados, há um backtrace (o fluxo de funções que o computador levou para chegar a uma determinada função que travou, e (em nosso exemplo) quebrou a pilha) não faz mais sentido.

Em termos gerais, quando olhamos para um backtrace, terá um fluxo claro de funções que foram chamadas. Embora um programa com falha não possa ser chamado imediatamente de 'saudável', em termos de recuo / depuração, é assim que se parece um retrocesso "saudável":

Uma pilha 'saudável' via backtrace (bt) usando GDB

Apesar disto, quando a bateria está ruim, a depuração se torna muito mais difícil. A pilha pode ter esta aparência:

Um dump de pilha esmagador gerado pelo mysqld, o servidor de banco de dados MySQL

Este é um exemplo de um problema de quebra de pilha que aconteceu no MySQL, o servidor de banco de dados (Pedir ao log.txt anexado a Erro de MySQL 37815 para saída total) sobre 2008, que causou o daemon do servidor de banco de dados (mysqld) para terminar.

Enquanto a biblioteca do sistema operacional libc.so.6, nesta circunstância, parece ter lidado com a quebra de pilha muito bem (usando alguma funcionalidade de fortificação no __fortify_fail função), o problema existia em algum lugar do código e já foi corrigido.

Observe também que, nesta circunstância, não vemos nomes de funções resolvidos, só nos é mostrado o nome binário (curiosamente, o problema parece ter sido com o cliente (mysql) causando o servidor (mysqld) para terminar) o que é mysql, junto com um endereço de memória da função: mysql[0x8051565], mysql[0x80525c7] e mysql(main+0x4f8)[0x8053198].

Regularmente, quando usamos símbolos de depuração (veja abaixo uma postagem no GDB que explica o que são os símbolos de depuração em detalhes), veríamos nomes de funções com variáveis, e até mesmo com alguns níveis de otimização / Minificação binária implementada, pelo menos veríamos os nomes das funções, como o que vemos no primeiro backtrace ‘saudável’ anterior.

Apesar disto, no caso de uma bateria quebrada, a saída dos nomes das funções, nomes ou valores de variáveis ​​nunca são garantidos e, frequentemente, um palavreado é concluído 🙂 Podemos até ver nomes diferentes de funções ou um pilha quebrada (outro jargão frequentemente usado pelo pessoal de TI) nomes de funções diferentes que não fazem muito sentido (e provavelmente são fictícios / falso, pois a pilha foi de alguma forma sobrescrita).

Isso torna mais difícil para o engenheiro de teste (que pode acabar com muitos resultados diferentes para um único erro, o que complica o manuseio do mecanismo de filtragem de erros conhecido) quanto ao desenvolvedor (que você provavelmente terá que usar um rastreamento passo a passo ou um depurador de execução reversa como RR para descobrir o erro em questão).

O que fazer quando você enfrentar Stack Smashing?

Se você encontrar baterias quebradas, a primeira coisa que você precisa fazer é entender um pouco melhor o problema e o ambiente para saber a fonte. Se você tiver um servidor da Web popular exposto na Internet com muitos usuários do jogo tentando ganhar um torneio enquanto o servidor também está minando Bitcoin, você vai querer aproveitar uma oportunidade de jogo sujo e descobrir se alguém está mexendo com o servidor.

Apesar disto, na maioria dos casos, o problema será apenas um erro de aplicativo. Enquanto eu digo 'só’, o problema pode ser muito importante, pode resultar em tempo de inatividade dos serviços, pode custar muito dinheiro e, para terminar, não pode ser consertado. Como um exemplo, um servidor de banco de dados pode falhar persistentemente quando iniciado devido aos dados estarem em um determinado estado em combinação com uma deficiência ou limitação no código.

Se tal situação for agravada por não quebrar a bateria, ou dito de outra forma, não sendo capaz de gerar um acompanhamento limpo do problema, a depuração será mais complicada e, às vezes, quase impossível. Apesar disto, não temas, a mesma depuração básica de quaisquer bugs ou erros / fracasso / o problema de aplicação continua o mesmo.

Por favor, leia todos os arquivos de log cuidadosamente antes, durante e depois que o problema ocorreu. Faça alguns backups e tente a operação novamente. Falha de novo ou não? Investigue os bugs, as partes da pilha e até mesmo os quadros (Em outras palavras, as funções de pilha individuais exibidas, como ele do_the_maths função em nosso 'rastreamento de pilha saudável’ original) pode ser colocado em seus motores de busca favoritos.

Concatenar (com um espaço) os quadros bloqueados mais seletivos (superior) e pesquisar o mesmo online geralmente fornece um relatório de bug existente para o problema que você está enfrentando. Ainda assim, no caso de quebra de bateria, esses frames são prováveis (nomes de funções) foram estragados e, por isso, não pode mais ser usado da mesma maneira. Se você vir uma mensagem de afirmação (uma afirmação instituída pelo desenvolvedor no código) de qualquer tipo, procure também.

Sempre envie um novo relatório de bug se o problema ainda não parece ter sido registrado online (Você pode estar ajudando outras pessoas que estão vendo o mesmo!) E forneça o máximo de informações sobre o problema que puder encontrar. Centenas de relatórios de bug em tantos aplicativos são registrados online todos os dias. Com sorte, a equipe de suporte do seu aplicativo de destruição de pilha está habilitada para ajudá-lo rapidamente.

Você também pode gostar de ler nosso post Debugging with GDB: Introdução abaixo, uma vez que é baseado em como os programas C e C podem ser depurados ++ (e outros) com depurador GDB. Ele também explica em mais detalhes os conceitos de uma pilha.

Assine a nossa newsletter

Nós não enviaremos SPAM para você. Nós odiamos isso tanto quanto você.