É seguro confiar na análise estática para "reproduzir" erros de simultaneidade de maneira confiável?

8

Eu herdei algum código Java que, suspeito, abriga alguns erros de simultaneidade ao sincronizar entre um encadeamento que consulta dados e um evento de E / S que atualiza os mesmos dados. Estou testando uma ferramenta de análise estática chamada ThreadSafe, que de fato detecta vários problemas de simultaneidade (ou seja, campo acessado pelo método invocado de forma assíncrona sem sincronização e sincronização inconsistente de acessos a uma coleção).

Depois de descobrir como é difícil reproduzir as corridas de dados de maneira confiável, escrevendo testes de unidade, perguntei-me se seria aconselhável depender do ThreadSafe para "reproduzir" os erros de maneira confiável. O que estou perguntando é: é seguro depender da ferramenta de análise estática para me dizer quando corrigi os bugs? (Obviamente, para corrigir os erros, precisarei entender cada um no contexto).

doughgle
fonte
3
###
6
Portanto, em outras palavras, sua pergunta é "a análise estática tem falsos negativos".
@ delnan: EXTREMAMENTE convincente, comentário perspicaz. +100 se eu puder.
John R. Strohm

Respostas:

3

Respondendo à sua primeira pergunta:

http://www.contemplateltd.com/threadsafe/faq#non-checkers

"Que tipos de defeitos de simultaneidade o ThreadSafe não procura?

  • Ainda não incluímos suporte para todos os java.util.concurrent. Especificamente, o ThreadSafe não verifica o uso indevido dos recursos avançados de sincronização fornecidos pelo java.util.concurrent, por exemplo, o pacote java.util.concurrent.atomic. Atualmente, ele também não inclui verificadores de erros que podem ocorrer ao gravar programas paralelos usando a estrutura Fork-Join.

  • Encontrar bugs em algoritmos intrincados sem bloqueios requer uma tecnologia de análise que não se adapta bem. Esses algoritmos devem ser deixados para especialistas especializados em concorrência. O ThreadSafe pode ser configurado para encontrar defeitos nos aplicativos que usam bibliotecas que contêm esses algoritmos.

  • As análises que incluímos em novas versões do ThreadSafe são ditadas tanto pelo que é possível usar a tecnologia de análise madura o suficiente para a integração em um produto utilizável quanto pelos recursos e defeitos de simultaneidade que vemos frequentemente em programas Java "comuns".

  • Se você tiver um problema de simultaneidade Java que atualmente não é coberto pelo ThreadSafe, os especialistas em simultâneo em Java da Contemplate poderão ajudar, adicionando configurações personalizadas ao ThreadSafe e / ou usando a tecnologia de análise avançada que ainda não está madura o suficiente para a integração ao ThreadSafe. "

Den
fonte
1
Nota para si mesmo: RTFM! Isso responde à minha pergunta.
doughgle
8

Na minha experiência, um desenvolvedor determinado, bem-intencionado, mas sem noção, pode ocultar a ofuscação suficiente em torno de um bug de simultaneidade que a ferramenta de análise não entenderá.

Se a ferramenta achar que há um erro, assuma que está correto até que você prove o contrário. Esse é o valor da ferramenta. Se a ferramenta não encontrar nenhum erro, sua melhor aposta é fingir que a ferramenta não existe.

Se você deseja um código simultâneo confiável (em qualquer idioma), seus objetivos devem incluir:

  1. As seções críticas devem ser minúsculas e simples, para que sejam fáceis de entender.
  2. As seções críticas devem ser completamente isoladas de outro código no nível da fonte.
  3. Uma função / método / sub-rotina envolvida no código simultâneo deve fazer apenas uma coisa . Se ele manipula uma primitiva de sincronização (bloqueio, semáforo etc.), NÃO deve mexer com nenhum dos recursos compartilhados e NÃO deve conter loops ou código condicional. Mova o "trabalho real" para uma função separada. Isso suporta o item 1.
  4. Se você tiver algum tipo de bloqueio, o desenvolvedor poderá ler o código e determinar exatamente quais recursos esse bloqueio protege em 30 segundos ou menos. Se não for óbvio para você, não será óbvio para o próximo cara. E provavelmente não ficou claro para o sujeito que escreveu o código. Então provavelmente está quebrado.
  5. A visibilidade do recurso que você está protegendo não deve ser maior que a visibilidade da primitiva de sincronização que o protege. Nenhum componente deve estar visível para o corpo maior do código.
  6. Etc. O restante da lista é realmente apenas uma variedade de maneiras de atualizar os itens 1 e 2.

Se o seu código foi projetado e organizado corretamente, você poderá analisar uma pequena fração do código para entender e confiar na simultaneidade. Quando você alcançar esse objetivo, em seguida, alimentar o código para a ferramenta de análise estática e ver se ele concorda.

E forneça o código para alguns outros desenvolvedores não-guru para revisão. Peça que expliquem como a simultaneidade funciona e por que está correta. Se eles não conseguem explicar, ainda é muito complexo.

GraniteRobert
fonte
2
algo a acrescentar a 4: cada recurso protegido por uma fechadura deve ser documentada de que está protegido pela fechadura e nunca deve ser utilizado longe de onde o bloqueio é adquirido
catraca aberração
1
Algo a acrescentar: 6) NUNCA adquira e mantenha mais de um bloqueio a qualquer momento. 7) Se você absolutamente, positivamente, DEVE adquirir e manter mais de um bloqueio em um dado instante, certifique-se de que SEMPRE sejam adquiridos na mesma ordem. Se o processo A e o processo B precisarem adquirir bloqueios vermelho e verde, eles poderão travar se um adquirir o vermelho primeiro e o outro adquirir o verde primeiro.
John R. Strohm
2

Produzir uma ferramenta de análise estática útil envolve equilibrar uma série de preocupações conflitantes, incluindo pelo menos o seguinte:

  • Taxa de falso positivo (alarme falso)
  • Taxa de falso negativo (bug não detectado)
  • Tempo de execução e escalabilidade

Os falsos positivos são uma preocupação crítica com as ferramentas de detecção de erros, pois perdem tempo do desenvolvedor. É possível eliminar falsos negativos, mas para muitos tipos de erros, incluindo erros de simultaneidade, isso envolveria um aumento inaceitável na taxa de falsos positivos. A taxa de falsos positivos e falsos negativos pode ser reduzida com o aumento do tempo de execução, mas as técnicas de análise mais precisas não vão além de pequenas aplicações e, de qualquer forma, não podem ser reduzidas a zero.

As ferramentas de análise dinâmica geralmente reivindicam uma taxa de falsos positivos de 0%, mas isso ocorre porque eles só encontram bugs quando realmente acontecem. Para uma condição de corrida ou impasse que acontece apenas uma vez na lua azul, isso não é tão útil.

Por esses motivos, o ThreadSafe não promete encontrar todos os erros de simultaneidade - ele visa encontrar os mais importantes, com uma baixa taxa de falsos positivos. Alguns usuários tentaram o ThreadSafe no código com um bug de simultaneidade conhecido que eles levaram dias para encontrar e descobriram que o bug - e muitas vezes outros erros genuínos que eles desconheciam - sem falsos positivos, em minutos.

Um bom ponto de partida para obter informações sobre o ThreadSafe é este artigo da InfoQ . Para obter mais informações, consulte o site ThreadSafe, onde você pode se inscrever para uma avaliação gratuita.

(Divulgação: ThreadSafe é uma ferramenta comercial e sou co-fundador da Contemplate, a empresa que a produz.)

dsannella
fonte